DateTimeConstraintTest.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. <?php
  2. namespace App\Tests\Unit\Service\Constraint;
  3. use App\Entity\Access\Access;
  4. use App\Entity\Organization\Organization;
  5. use App\Entity\Organization\Parameters;
  6. use App\Repository\Access\AccessRepository;
  7. use App\Service\Constraint\DateTimeConstraint;
  8. use App\Service\Organization\Utils as OrganizationUtils;
  9. use App\Tests\Unit\TestToolsTrait;
  10. use Doctrine\ORM\EntityManagerInterface;
  11. use PHPUnit\Framework\MockObject\MockObject;
  12. use PHPUnit\Framework\TestCase;
  13. class TestableDateTimeConstraint extends DateTimeConstraint
  14. {
  15. public function hasCustomPeriods($historical): bool
  16. {
  17. return parent::hasCustomPeriods($historical);
  18. }
  19. public function addConstraint(array $contraints, array $newContraint): array
  20. {
  21. return parent::addConstraint($contraints, $newContraint);
  22. }
  23. public function cleanConstraints(array $constraints): array
  24. {
  25. return parent::cleanConstraints($constraints);
  26. }
  27. public function getCustomPeriods(string $dateStart, string $dateEnd): array
  28. {
  29. return parent::getCustomPeriods($dateStart, $dateEnd);
  30. }
  31. public function getPeriods(Access $access): array
  32. {
  33. return parent::getPeriods($access);
  34. }
  35. public function presentConstraint(array $periods): array
  36. {
  37. return parent::presentConstraint($periods);
  38. }
  39. public function pastConstraint($periods): array
  40. {
  41. return parent::pastConstraint($periods);
  42. }
  43. public function futureConstraint($periods): array
  44. {
  45. return parent::futureConstraint($periods);
  46. }
  47. }
  48. class DateTimeConstraintTest extends TestCase
  49. {
  50. use TestToolsTrait;
  51. private MockObject|OrganizationUtils $organizationUtils;
  52. private MockObject|EntityManagerInterface $entityManager;
  53. private array $periods;
  54. public function setUp(): void
  55. {
  56. $this->entityManager = $this->getMockBuilder(EntityManagerInterface::class)->disableOriginalConstructor()->getMock();
  57. $this->organizationUtils = $this->getMockBuilder(OrganizationUtils::class)->disableOriginalConstructor()->getMock();
  58. $this->periods = [
  59. 'dateStart' => '2021-12-20',
  60. 'dateEnd' => '2022-08-31',
  61. ];
  62. }
  63. /**
  64. * @see DateTimeConstraint::invoke()
  65. */
  66. public function testInvokePresentNoCustomPeriods(): void
  67. {
  68. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  69. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  70. ->setMethodsExcept(['invoke'])
  71. ->getMock();
  72. $access = $this->getMockBuilder(Access::class)->getMock();
  73. $accessRepository = $this->getMockBuilder(AccessRepository::class)->disableOriginalConstructor()->getMock();
  74. $accessRepository->method('find')->with(123)->willReturn($access);
  75. $this->entityManager->method('getRepository')->with(Access::class)->willReturn($accessRepository);
  76. $historical = ['future' => false, 'past' => false, 'present' => true, 'dateStart' => null, 'dateEnd' => null];
  77. $access->method('getHistorical')->willReturn($historical);
  78. $dateTimeConstraint->method('hasCustomPeriods')->with($historical)->willReturn(false);
  79. $periods = ['dateStart' => '2020-01-01', 'dateEnd' => '2020-12-31'];
  80. $dateTimeConstraint->method('getPeriods')->with($access)->willReturn($periods);
  81. $constraint = ['foo'];
  82. $dateTimeConstraint->method('presentConstraint')->with($periods)->willReturn($constraint);
  83. $dateTimeConstraint
  84. ->expects(self::once())
  85. ->method('addConstraint')
  86. ->with(['start' => [], 'end' => []], $constraint)
  87. ->willReturn(['bar']);
  88. $dateTimeConstraint
  89. ->expects(self::once())
  90. ->method('cleanConstraints')
  91. ->with(['bar']);
  92. $dateTimeConstraint->invoke(123);
  93. }
  94. /**
  95. * @see DateTimeConstraint::invoke()
  96. */
  97. public function testInvokePastNoCustomPeriods(): void
  98. {
  99. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  100. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  101. ->setMethodsExcept(['invoke'])
  102. ->getMock();
  103. $access = $this->getMockBuilder(Access::class)->getMock();
  104. $accessRepository = $this->getMockBuilder(AccessRepository::class)->disableOriginalConstructor()->getMock();
  105. $accessRepository->method('find')->with(123)->willReturn($access);
  106. $this->entityManager->method('getRepository')->with(Access::class)->willReturn($accessRepository);
  107. $historical = ['future' => false, 'past' => true, 'present' => false, 'dateStart' => null, 'dateEnd' => null];
  108. $access->method('getHistorical')->willReturn($historical);
  109. $dateTimeConstraint->method('hasCustomPeriods')->with($historical)->willReturn(false);
  110. $periods = ['dateStart' => '2020-01-01', 'dateEnd' => '2020-12-31'];
  111. $dateTimeConstraint->method('getPeriods')->with($access)->willReturn($periods);
  112. $constraint = ['foo'];
  113. $dateTimeConstraint->method('pastConstraint')->with($periods)->willReturn($constraint);
  114. $dateTimeConstraint
  115. ->expects(self::once())
  116. ->method('addConstraint')
  117. ->with(['start' => [], 'end' => []], $constraint)
  118. ->willReturn(['bar']);
  119. $dateTimeConstraint
  120. ->expects(self::once())
  121. ->method('cleanConstraints')
  122. ->with(['bar']);
  123. $dateTimeConstraint->invoke(123);
  124. }
  125. /**
  126. * @see DateTimeConstraint::invoke()
  127. */
  128. public function testInvokeFutureNoCustomPeriods(): void
  129. {
  130. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  131. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  132. ->setMethodsExcept(['invoke'])
  133. ->getMock();
  134. $access = $this->getMockBuilder(Access::class)->getMock();
  135. $accessRepository = $this->getMockBuilder(AccessRepository::class)->disableOriginalConstructor()->getMock();
  136. $accessRepository->method('find')->with(123)->willReturn($access);
  137. $this->entityManager->method('getRepository')->with(Access::class)->willReturn($accessRepository);
  138. $historical = ['future' => true, 'past' => false, 'present' => false, 'dateStart' => null, 'dateEnd' => null];
  139. $access->method('getHistorical')->willReturn($historical);
  140. $dateTimeConstraint->method('hasCustomPeriods')->with($historical)->willReturn(false);
  141. $periods = ['dateStart' => '2020-01-01', 'dateEnd' => '2020-12-31'];
  142. $dateTimeConstraint->method('getPeriods')->with($access)->willReturn($periods);
  143. $constraint = ['foo'];
  144. $dateTimeConstraint->method('futureConstraint')->with($periods)->willReturn($constraint);
  145. $dateTimeConstraint
  146. ->expects(self::once())
  147. ->method('addConstraint')
  148. ->with(['start' => [], 'end' => []], $constraint)
  149. ->willReturn(['bar']);
  150. $dateTimeConstraint
  151. ->expects(self::once())
  152. ->method('cleanConstraints')
  153. ->with(['bar']);
  154. $dateTimeConstraint->invoke(123);
  155. }
  156. /**
  157. * @see DateTimeConstraint::invoke()
  158. */
  159. public function testInvokeMultiplePeriodsNoCustom(): void
  160. {
  161. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  162. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  163. ->setMethodsExcept(['invoke'])
  164. ->getMock();
  165. $access = $this->getMockBuilder(Access::class)->getMock();
  166. $accessRepository = $this->getMockBuilder(AccessRepository::class)->disableOriginalConstructor()->getMock();
  167. $accessRepository->method('find')->with(123)->willReturn($access);
  168. $this->entityManager->method('getRepository')->with(Access::class)->willReturn($accessRepository);
  169. $historical = ['future' => true, 'past' => true, 'present' => true, 'dateStart' => null, 'dateEnd' => null];
  170. $access->method('getHistorical')->willReturn($historical);
  171. $dateTimeConstraint->method('getPeriods')->with($access)->willReturn(['dateStart' => '2020-01-01', 'dateEnd' => '2020-12-31']);
  172. $dateTimeConstraint->method('hasCustomPeriods')->with($historical)->willReturn(false);
  173. $dateTimeConstraint->method('pastConstraint')->willReturn(['pastConstraint']);
  174. $dateTimeConstraint->method('presentConstraint')->willReturn(['presentConstraint']);
  175. $dateTimeConstraint->method('futureConstraint')->willReturn(['futureConstraint']);
  176. $dateTimeConstraint
  177. ->expects(self::exactly(3))
  178. ->method('addConstraint')
  179. ->withConsecutive(
  180. [['start' => [], 'end' => []], ['presentConstraint']],
  181. [['start' => [], 'end' => []], ['pastConstraint']],
  182. [['start' => [], 'end' => []], ['futureConstraint']]
  183. )->willReturn(['start' => [], 'end' => []]);
  184. $dateTimeConstraint
  185. ->expects(self::once())
  186. ->method('cleanConstraints')
  187. ->with(['start' => [], 'end' => []]);
  188. $dateTimeConstraint->invoke(123);
  189. }
  190. /**
  191. * @see DateTimeConstraint::invoke()
  192. */
  193. public function testInvokeWithCustom(): void
  194. {
  195. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  196. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  197. ->setMethodsExcept(['invoke'])
  198. ->getMock();
  199. $access = $this->getMockBuilder(Access::class)->getMock();
  200. $accessRepository = $this->getMockBuilder(AccessRepository::class)->disableOriginalConstructor()->getMock();
  201. $accessRepository->method('find')->with(123)->willReturn($access);
  202. $this->entityManager->method('getRepository')->with(Access::class)->willReturn($accessRepository);
  203. $historical = ['future' => false, 'past' => false, 'present' => true, 'dateStart' => '2020-01-01', 'dateEnd' => '2020-02-01'];
  204. $access->method('getHistorical')->willReturn($historical);
  205. $dateTimeConstraint->method('hasCustomPeriods')->with($historical)->willReturn(true);
  206. $dateTimeConstraint->expects(self::never())->method('pastConstraint');
  207. $dateTimeConstraint->expects(self::never())->method('futureConstraint');
  208. $dateTimeConstraint
  209. ->method('getCustomPeriods')
  210. ->with('2020-01-01', '2020-02-01')
  211. ->willReturn(['dateStart' => 2020, 'dateEnd' => 2020]);
  212. $dateTimeConstraint->expects(self::once())
  213. ->method('presentConstraint')
  214. ->with(['dateStart' => 2020, 'dateEnd' => 2020])
  215. ->willReturn(['bar']);
  216. $dateTimeConstraint
  217. ->expects(self::once())
  218. ->method('addConstraint')
  219. ->with(['start' => [], 'end' => []], ['bar'])
  220. ->willReturn(['start' => [], 'end' => []]);
  221. $dateTimeConstraint
  222. ->expects(self::once())
  223. ->method('cleanConstraints')
  224. ->with(['start' => [], 'end' => []]);
  225. $dateTimeConstraint->invoke(123);
  226. }
  227. /**
  228. * @see DateTimeConstraint::getCustomPeriods()
  229. */
  230. public function testGetCustomPeriods(): void
  231. {
  232. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  233. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  234. ->setMethodsExcept(['getCustomPeriods'])
  235. ->getMock();
  236. $this->assertEquals(
  237. ['dateStart' => '2020-01-01', 'dateEnd' => '2020-12-31'],
  238. $dateTimeConstraint->getCustomPeriods('2020-01-01', '2020-12-31')
  239. );
  240. }
  241. /**
  242. * @see DateTimeConstraint::presentConstraint()
  243. */
  244. public function testPresentConstraint(): void
  245. {
  246. $expected = [
  247. 'start' => [
  248. '2022-08-31' => 4,
  249. ],
  250. 'end' => [
  251. '2021-12-20' => 8,
  252. 'NULL' => 0,
  253. ],
  254. ];
  255. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  256. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  257. ->setMethodsExcept(['presentConstraint'])
  258. ->getMock();
  259. $result = $this->invokeMethod($dateTimeConstraint, 'presentConstraint', [$this->periods]);
  260. $this->assertEquals($expected, $result);
  261. }
  262. /**
  263. * @see DateTimeConstraint::pastConstraint()
  264. */
  265. public function testPastConstraint(): void
  266. {
  267. $expected = [
  268. 'end' => [
  269. '2021-12-20' => 1,
  270. ],
  271. ];
  272. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  273. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  274. ->setMethodsExcept(['pastConstraint'])
  275. ->getMock();
  276. $result = $this->invokeMethod($dateTimeConstraint, 'pastConstraint', [$this->periods]);
  277. $this->assertEquals($expected, $result);
  278. }
  279. /**
  280. * @see DateTimeConstraint::futurConstraint()
  281. */
  282. public function testFutureConstraint(): void
  283. {
  284. $expected = [
  285. 'start' => [
  286. '2022-08-31' => 5,
  287. ],
  288. ];
  289. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  290. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  291. ->setMethodsExcept(['futureConstraint'])
  292. ->getMock();
  293. $result = $this->invokeMethod($dateTimeConstraint, 'futureConstraint', [$this->periods]);
  294. $this->assertEquals($expected, $result);
  295. }
  296. /**
  297. * Si l'année courante est l'année d'affichage choisie par l'utilisateur, alors la date de début est aujourd'hui.
  298. *
  299. * @throws \ReflectionException
  300. *
  301. * @see DateTimeConstraint::getPeriods()
  302. */
  303. public function testGetPeriodsToday(): void
  304. {
  305. $today = new \DateTime('now');
  306. $activityYear = (int) $today->format('Y');
  307. if ((int) $today->format('m') < 9) {
  308. --$activityYear;
  309. }
  310. $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
  311. $parameters->method('getMusicalDate')->willReturn(new \DateTime('2000-09-01'));
  312. $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
  313. $organization->method('getParameters')->willReturn($parameters);
  314. $access = $this->getMockBuilder(Access::class)->disableOriginalConstructor()->getMock();
  315. $access->method('getOrganization')->willReturn($organization);
  316. $access->method('getActivityYear')->willReturn(2020);
  317. $this->organizationUtils->method('getOrganizationCurrentActivityYear')->with($organization)->willReturn(2020);
  318. $this->organizationUtils
  319. ->method('getActivityPeriodsSwitchYear')
  320. ->with($organization, 2020)
  321. ->willReturn(['dateStart' => 'YEAR-09-01', 'dateEnd' => ($activityYear + 1).'-08-31']); // dateStart will be overwritten
  322. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  323. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  324. ->setMethodsExcept(['getPeriods'])
  325. ->getMock();
  326. $periodExpected = ['dateStart' => $today->format('Y-m-d'), 'dateEnd' => ($activityYear + 1).'-08-31'];
  327. $result = $this->invokeMethod($dateTimeConstraint, 'getPeriods', [$access]);
  328. $this->assertEquals($periodExpected, $result);
  329. }
  330. /**
  331. * @throws \ReflectionException
  332. *
  333. * @see DateTimeConstraint::getPeriods()
  334. */
  335. public function testGetPeriodsNotToday(): void
  336. {
  337. $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
  338. $access = $this->getMockBuilder(Access::class)->disableOriginalConstructor()->getMock();
  339. $access->method('getOrganization')->willReturn($organization);
  340. $access->method('getActivityYear')->willReturn(2020);
  341. $this->organizationUtils->method('getOrganizationCurrentActivityYear')->with($organization)->willReturn(2022);
  342. $this->organizationUtils
  343. ->method('getActivityPeriodsSwitchYear')
  344. ->with($organization, 2020)
  345. ->willReturn(['dateStart' => '2020-09-01', 'dateEnd' => '2021-08-31']);
  346. $dateTimeConstraint = $this->getMockBuilder(TestableDateTimeConstraint::class)
  347. ->setConstructorArgs([$this->entityManager, $this->organizationUtils])
  348. ->setMethodsExcept(['getPeriods'])
  349. ->getMock();
  350. $periodExpected = ['dateStart' => '2020-09-01', 'dateEnd' => '2021-08-31'];
  351. $this->assertEquals($periodExpected, $this->invokeMethod($dateTimeConstraint, 'getPeriods', [$access]));
  352. }
  353. }