AccessProfileCreatorTest.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. <?php
  2. namespace App\Tests\Unit\Service\Access;
  3. use App\ApiResources\Profile\AccessProfile;
  4. use App\ApiResources\Profile\OrganizationProfile;
  5. use App\Entity\Access\Access;
  6. use App\Entity\Access\Preferences;
  7. use App\Entity\Core\File;
  8. use App\Entity\Organization\Organization;
  9. use App\Entity\Person\Person;
  10. use App\Enum\Person\GenderEnum;
  11. use App\Repository\Access\AccessRepository;
  12. use App\Service\Access\AccessProfileCreator;
  13. use App\Service\Access\Utils as AccessUtils;
  14. use App\Service\Organization\OrganizationProfileCreator;
  15. use Doctrine\Common\Collections\ArrayCollection;
  16. use Doctrine\Common\Collections\Collection;
  17. use Doctrine\ORM\EntityManagerInterface;
  18. use PHPUnit\Framework\MockObject\MockObject;
  19. use PHPUnit\Framework\TestCase;
  20. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  21. class AccessProfileCreatorTest extends TestCase
  22. {
  23. private MockObject|OrganizationProfileCreator $organizationProfileCreator;
  24. private MockObject|AccessRepository $accessRepository;
  25. private MockObject|AccessUtils $accessUtils;
  26. private MockObject|AccessProfileCreator $accessProfileCreator;
  27. private MockObject|AccessProfile $accessProfile;
  28. private MockObject|Collection $emptyCollection;
  29. private MockObject|Collection $nonEmptyCollection;
  30. private MockObject|Organization $organization;
  31. private MockObject|Access $access;
  32. private MockObject|OrganizationProfile $organizationProfile;
  33. private MockObject|EntityManagerInterface $entityManager;
  34. private MockObject|Preferences $preferences;
  35. public function setUp(): void
  36. {
  37. $this->organizationProfileCreator = $this->getMockBuilder(OrganizationProfileCreator::class)->disableOriginalConstructor()->getMock();
  38. $this->accessRepository = $this->getMockBuilder(AccessRepository::class)->disableOriginalConstructor()->getMock();
  39. $this->accessUtils = $this->getMockBuilder(AccessUtils::class)->disableOriginalConstructor()->getMock();
  40. $this->entityManager = $this->getMockBuilder(EntityManagerInterface::class)->disableOriginalConstructor()->getMock();
  41. $this->emptyCollection = $this->getMockBuilder(Collection::class)->getMock();
  42. $this->emptyCollection->method('isEmpty')->willReturn(true);
  43. $this->nonEmptyCollection = $this->getMockBuilder(Collection::class)->getMock();
  44. $this->nonEmptyCollection->method('isEmpty')->willReturn(false);
  45. $this->organization = $this->getMockBuilder(Organization::class)->getMock();
  46. $this->access = $this->getMockBuilder(Access::class)->getMock();
  47. $this->organizationProfile = $this->getMockBuilder(OrganizationProfile::class)->getMock();
  48. $this->accessProfile = $this->getMockBuilder(AccessProfile::class)->getMock();
  49. $this->preferences = $this->getMockBuilder(Preferences::class)->getMock();
  50. }
  51. /**
  52. * @see AccessProfileCreator::getAccessProfile()
  53. */
  54. public function testGetAccessProfileFailed(): void
  55. {
  56. $this->accessProfileCreator = $this
  57. ->getMockBuilder(AccessProfileCreator::class)
  58. ->setConstructorArgs([$this->organizationProfileCreator, $this->accessRepository, $this->accessUtils, $this->entityManager])
  59. ->setMethodsExcept(['getAccessProfile'])
  60. ->getMock();
  61. $this->accessRepository
  62. ->method('findAllValidAccesses')
  63. ->with($this->access)
  64. ->willReturn([]);
  65. $this->expectException(AuthenticationException::class);
  66. $this->accessProfileCreator->getAccessProfile($this->access);
  67. }
  68. /**
  69. * Access valide avec multicompte et famille.
  70. *
  71. * @see AccessProfileCreator::getAccessProfile()
  72. */
  73. public function testGetAccessProfile(): void
  74. {
  75. $accessProfileCreator = $this
  76. ->getMockBuilder(AccessProfileCreator::class)
  77. ->setConstructorArgs([$this->organizationProfileCreator, $this->accessRepository, $this->accessUtils, $this->entityManager])
  78. ->setMethodsExcept(['getAccessProfile'])
  79. ->getMock();
  80. $otherAccess1 = $this->getMockBuilder(Access::class)->getMock();
  81. $otherAccess2 = $this->getMockBuilder(Access::class)->getMock();
  82. // Find valid accesses
  83. $this->accessRepository
  84. ->method('findAllValidAccesses')
  85. ->with($this->access)
  86. ->willReturn([$this->access, $otherAccess1, $otherAccess2]);
  87. // Find valid accesses
  88. $this->access
  89. ->method('getPreferences')
  90. ->willReturn(null);
  91. // create the profile
  92. $accessProfileCreator
  93. ->expects(self::once())
  94. ->method('createPreferences')
  95. ->with($this->access);
  96. // create the profile
  97. $accessProfileCreator
  98. ->expects(self::once())
  99. ->method('createCompleteAccessProfile')
  100. ->with($this->access)
  101. ->willReturn($this->accessProfile);
  102. // Multi compte
  103. $otherOrganization1 = $this->getMockBuilder(Organization::class)->getMock();
  104. $otherOrganization2 = $this->getMockBuilder(Organization::class)->getMock();
  105. $otherAccess1->method('getOrganization')->willReturn($otherOrganization1);
  106. $otherAccess2->method('getOrganization')->willReturn($otherOrganization2);
  107. $otherOrganizationProfile1 = $this->getMockBuilder(OrganizationProfile::class)->getMock();
  108. $otherOrganizationProfile2 = $this->getMockBuilder(OrganizationProfile::class)->getMock();
  109. $this->organizationProfileCreator
  110. ->expects(self::exactly(2))
  111. ->method('createLightOrganizationProfile')
  112. ->willReturnMap(
  113. [
  114. [$otherOrganization1, $otherOrganizationProfile1],
  115. [$otherOrganization2, $otherOrganizationProfile2],
  116. ]
  117. );
  118. $this->accessUtils
  119. ->expects(self::once())
  120. ->method('filterAccesses')
  121. ->with([$this->access, $otherAccess1, $otherAccess2], $this->access)
  122. ->willReturn([$otherAccess1, $otherAccess2]);
  123. $this->accessProfile
  124. ->expects(self::exactly(2))
  125. ->method('addMultiAccess')
  126. ->withConsecutive(
  127. [$otherOrganizationProfile1],
  128. [$otherOrganizationProfile2]
  129. );
  130. // Accesses famille
  131. $children1 = $this->getMockBuilder(Access::class)->getMock();
  132. $children2 = $this->getMockBuilder(Access::class)->getMock();
  133. $childrenProfile1 = $this->getMockBuilder(AccessProfile::class)->getMock();
  134. $childrenProfile2 = $this->getMockBuilder(AccessProfile::class)->getMock();
  135. $this->access->expects(self::once())->method('getChildren')->willReturn(new ArrayCollection([$children1, $children2]));
  136. $accessProfileCreator
  137. ->expects(self::exactly(2))
  138. ->method('createLightAccessProfile')
  139. ->willReturnMap([
  140. [$children1, $childrenProfile1],
  141. [$children2, $childrenProfile2],
  142. ]);
  143. $this->accessProfile
  144. ->expects(self::exactly(2))
  145. ->method('addFamilyAccess')
  146. ->withConsecutive(
  147. [$childrenProfile1],
  148. [$childrenProfile2]
  149. );
  150. $accessProfileCreator->getAccessProfile($this->access);
  151. }
  152. /**
  153. * Test d'un access en compte switch.
  154. *
  155. * @see AccessProfileCreator::getAccessProfile()
  156. */
  157. public function testGetAccessProfileSwitch(): void
  158. {
  159. $accessProfileCreator = $this
  160. ->getMockBuilder(AccessProfileCreator::class)
  161. ->setConstructorArgs([$this->organizationProfileCreator, $this->accessRepository, $this->accessUtils, $this->entityManager])
  162. ->setMethodsExcept(['getAccessProfile'])
  163. ->getMock();
  164. $this->accessRepository
  165. ->method('findAllValidAccesses')
  166. ->with($this->access)
  167. ->willReturn([$this->access]);
  168. $accessProfileCreator
  169. ->expects(self::once())
  170. ->method('createCompleteAccessProfile')
  171. ->with($this->access)
  172. ->willReturn($this->accessProfile);
  173. $this->accessUtils
  174. ->expects(self::once())
  175. ->method('filterAccesses')
  176. ->with([$this->access], $this->access)
  177. ->willReturn([]);
  178. $this->access->method('getChildren')->willReturn(new ArrayCollection([]));
  179. $originalAccess = $this->getMockBuilder(Access::class)->getMock();
  180. $originalAccessProfile = $this->getMockBuilder(AccessProfile::class)->getMock();
  181. $accessProfileCreator
  182. ->expects(self::once())
  183. ->method('createLightAccessProfile')
  184. ->with($originalAccess)
  185. ->willReturn($originalAccessProfile);
  186. $this->accessProfile->expects(self::once())->method('setOriginalAccess')->with($originalAccessProfile);
  187. $accessProfileCreator->getAccessProfile($this->access, $originalAccess);
  188. }
  189. /**
  190. * Setup mocks for the tests on createCompleteAccessProfile.
  191. *
  192. * @see AccessProfileCreator::createCompleteAccessProfile()
  193. */
  194. private function setupCreateCompleteAccessProfile(): void
  195. {
  196. $this->accessProfileCreator = $this
  197. ->getMockBuilder(AccessProfileCreator::class)
  198. ->setConstructorArgs([$this->organizationProfileCreator, $this->accessRepository, $this->accessUtils, $this->entityManager])
  199. ->setMethodsExcept(['createCompleteAccessProfile'])
  200. ->getMock();
  201. $this->access->expects(self::once())->method('getAdminAccess')->willReturn(true);
  202. $this->access->expects(self::once())->method('getHistorical')->willReturn(['present' => true]);
  203. $this->access->expects(self::once())->method('getOrganization')->willReturn($this->organization);
  204. $this->accessUtils->expects(self::once())->method('getAllRoles')->with($this->access)->willReturn(['FOO']);
  205. $this->organizationProfileCreator
  206. ->expects(self::once())
  207. ->method('createCompleteOrganizationProfile')
  208. ->with($this->organization)
  209. ->willReturn($this->organizationProfile);
  210. $this->accessProfile->method('setIsAdminAccess')->willReturnSelf();
  211. $this->accessProfile->method('setRoles')->willReturnSelf();
  212. $this->accessProfile->method('setHistorical')->willReturnSelf();
  213. $this->accessProfile->method('setOrganization')->willReturnSelf();
  214. $this->accessProfile->method('setIsGuardian')->willReturnSelf();
  215. $this->accessProfile->method('setIsPayor')->willReturnSelf();
  216. $this->accessProfileCreator
  217. ->expects(self::once())
  218. ->method('createLightAccessProfile')
  219. ->with($this->access)
  220. ->willReturn($this->accessProfile);
  221. }
  222. /**
  223. * Default situation: the access is neither guardian nor payer or admin.
  224. *
  225. * @see AccessProfileCreator::createCompleteAccessProfile()
  226. */
  227. public function testCreateCompleteAccessProfile(): void
  228. {
  229. $this->setupCreateCompleteAccessProfile();
  230. $this->access->method('getChildren')->willReturn($this->emptyCollection);
  231. $this->access->method('getBillingPayers')->willReturn($this->emptyCollection);
  232. $this->access->method('getBillingReceivers')->willReturn($this->emptyCollection);
  233. $this->access->method('getAccessIntangibles')->willReturn($this->emptyCollection);
  234. $this->access->method('getPreferences')->willReturn($this->preferences);
  235. $this->accessProfile->expects(self::once())->method('setIsAdminAccess')->with(true)->willReturnSelf();
  236. $this->accessProfile->expects(self::once())->method('setRoles')->with(['FOO'])->willReturnSelf();
  237. $this->accessProfile->expects(self::once())->method('setHistorical')->with(['present' => true])->willReturnSelf();
  238. $this->accessProfile->expects(self::once())->method('setOrganization')->with($this->organizationProfile)->willReturnSelf();
  239. $this->accessProfile->expects(self::once())->method('setIsGuardian')->with(false)->willReturnSelf();
  240. $this->accessProfile->expects(self::once())->method('setIsPayor')->with(false)->willReturnSelf();
  241. $this->preferences->expects(self::once())->method('getId')->willReturn(1);
  242. $this->accessProfileCreator->createCompleteAccessProfile($this->access);
  243. }
  244. /**
  245. * If the access has children, isGuardian shall be set to true.
  246. *
  247. * @see AccessProfileCreator::createCompleteAccessProfile()
  248. */
  249. public function testCreateCompleteAccessProfileIsGuardian(): void
  250. {
  251. $this->setupCreateCompleteAccessProfile();
  252. $this->access->method('getChildren')->willReturn($this->nonEmptyCollection);
  253. $this->access->method('getBillingPayers')->willReturn($this->emptyCollection);
  254. $this->access->method('getBillingReceivers')->willReturn($this->emptyCollection);
  255. $this->access->method('getAccessIntangibles')->willReturn($this->emptyCollection);
  256. $this->access->method('getPreferences')->willReturn($this->preferences);
  257. $this->accessProfile->expects(self::once())->method('setIsGuardian')->with(true)->willReturnSelf();
  258. $this->preferences->expects(self::once())->method('getId')->willReturn(1);
  259. $this->accessProfileCreator->createCompleteAccessProfile($this->access);
  260. }
  261. /**
  262. * If the access has billingPayers, isPayor shall be set to true.
  263. *
  264. * @see AccessProfileCreator::createCompleteAccessProfile()
  265. */
  266. public function testCreateCompleteAccessProfileIsPayorWithBillingPayer(): void
  267. {
  268. $this->setupCreateCompleteAccessProfile();
  269. $this->access->method('getChildren')->willReturn($this->emptyCollection);
  270. $this->access->method('getBillingPayers')->willReturn($this->nonEmptyCollection);
  271. $this->access->method('getBillingReceivers')->willReturn($this->emptyCollection);
  272. $this->access->method('getAccessIntangibles')->willReturn($this->emptyCollection);
  273. $this->access->method('getPreferences')->willReturn($this->preferences);
  274. $this->accessProfile->expects(self::once())->method('setIsPayor')->with(true)->willReturnSelf();
  275. $this->preferences->expects(self::once())->method('getId')->willReturn(1);
  276. $this->accessProfileCreator->createCompleteAccessProfile($this->access);
  277. }
  278. /**
  279. * If the access has no billingPayers but has AccessIntangible, isPayor shall be set to true.
  280. *
  281. * @see AccessProfileCreator::createCompleteAccessProfile()
  282. */
  283. public function testCreateCompleteAccessProfileIsPayorWithAccessIntangible(): void
  284. {
  285. $this->setupCreateCompleteAccessProfile();
  286. $this->access->method('getChildren')->willReturn($this->emptyCollection);
  287. $this->access->method('getBillingPayers')->willReturn($this->emptyCollection);
  288. $this->access->method('getBillingReceivers')->willReturn($this->emptyCollection);
  289. $this->access->method('getAccessIntangibles')->willReturn($this->nonEmptyCollection);
  290. $this->access->method('getPreferences')->willReturn($this->preferences);
  291. $this->accessProfile->expects(self::once())->method('setIsPayor')->with(true)->willReturnSelf();
  292. $this->preferences->expects(self::once())->method('getId')->willReturn(1);
  293. $this->accessProfileCreator->createCompleteAccessProfile($this->access);
  294. }
  295. /**
  296. * If the access has no billingPayers, has AccessIntangible but also have children, isPayor shall be set to false.
  297. *
  298. * @see AccessProfileCreator::createCompleteAccessProfile()
  299. */
  300. public function testCreateCompleteAccessProfileNotPayorWithAccessIntangibleBecauseChildren(): void
  301. {
  302. $this->setupCreateCompleteAccessProfile();
  303. $this->access->method('getChildren')->willReturn($this->nonEmptyCollection);
  304. $this->access->method('getBillingPayers')->willReturn($this->emptyCollection);
  305. $this->access->method('getBillingReceivers')->willReturn($this->emptyCollection);
  306. $this->access->method('getAccessIntangibles')->willReturn($this->nonEmptyCollection);
  307. $this->access->method('getPreferences')->willReturn($this->preferences);
  308. $this->accessProfile->expects(self::once())->method('setIsPayor')->with(false)->willReturnSelf();
  309. $this->preferences->expects(self::once())->method('getId')->willReturn(1);
  310. $this->accessProfileCreator->createCompleteAccessProfile($this->access);
  311. }
  312. /**
  313. * @see AccessProfileCreator::createLightAccessProfile()
  314. */
  315. public function testCreateLightAccessProfile(): void
  316. {
  317. $accessProfileCreator = $this
  318. ->getMockBuilder(AccessProfileCreator::class)
  319. ->setConstructorArgs([$this->organizationProfileCreator, $this->accessRepository, $this->accessUtils, $this->entityManager])
  320. ->setMethodsExcept(['createLightAccessProfile'])
  321. ->getMock();
  322. $image = $this->getMockBuilder(File::class)->getMock();
  323. $image->expects(self::once())->method('getId')->willReturn(123);
  324. $person = $this->getMockBuilder(Person::class)->getMock();
  325. $person->expects(self::once())->method('getName')->willReturn('Foo');
  326. $person->expects(self::once())->method('getGivenName')->willReturn('Bar');
  327. $person->expects(self::once())->method('getGender')->willReturn(GenderEnum::MISTER);
  328. $person->expects(self::once())->method('getImage')->willReturn($image);
  329. $this->access->expects(self::once())->method('getId')->willReturn(1);
  330. $this->access->method('getOrganization')->willReturn($this->organization);
  331. $this->access->method('getPerson')->willReturn($person);
  332. $this->access->expects(self::once())->method('getActivityYear')->willReturn(2020);
  333. $this->access->expects(self::once())->method('getSuperAdminAccess')->willReturn(false);
  334. $this->organizationProfileCreator
  335. ->expects(self::once())
  336. ->method('createLightOrganizationProfile')
  337. ->with($this->organization)
  338. ->willReturn($this->organizationProfile);
  339. $accessProfile = $accessProfileCreator->createLightAccessProfile($this->access);
  340. $this->assertEquals(1, $accessProfile->getId());
  341. $this->assertEquals('Foo', $accessProfile->getName());
  342. $this->assertEquals('Bar', $accessProfile->getGivenName());
  343. $this->assertEquals(GenderEnum::MISTER, $accessProfile->getGender());
  344. $this->assertEquals(2020, $accessProfile->getActivityYear());
  345. $this->assertEquals(123, $accessProfile->getAvatarId());
  346. $this->assertFalse($accessProfile->getIsSuperAdminAccess());
  347. $this->assertEquals($this->organizationProfile, $accessProfile->getOrganization());
  348. }
  349. /**
  350. * @see AccessProfileCreator::createPreferences()
  351. */
  352. public function testCreatePreferences(): void
  353. {
  354. $accessProfileCreator = $this
  355. ->getMockBuilder(AccessProfileCreator::class)
  356. ->setConstructorArgs([$this->organizationProfileCreator, $this->accessRepository, $this->accessUtils, $this->entityManager])
  357. ->setMethodsExcept(['createPreferences'])
  358. ->getMock();
  359. $this->access->expects(self::once())->method('setPreferences');
  360. $this->entityManager->expects(self::once())->method('flush');
  361. $accessProfileCreator->createPreferences($this->access);
  362. }
  363. }