CleanTempFilesTest.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <?php
  2. namespace App\Tests\Unit\Service\Cron\Job;
  3. use App\Entity\Core\File;
  4. use App\Enum\Core\FileHostEnum;
  5. use App\Enum\Core\FileStatusEnum;
  6. use App\Repository\Core\FileRepository;
  7. use App\Service\Cron\Job\CleanTempFiles;
  8. use App\Service\Cron\UI\CronUIInterface;
  9. use App\Service\File\Storage\LocalStorage;
  10. use App\Service\Utils\DatesUtils;
  11. use Doctrine\Common\Collections\ArrayCollection;
  12. use Doctrine\Common\Collections\Collection;
  13. use Doctrine\DBAL\Connection;
  14. use Doctrine\ORM\AbstractQuery;
  15. use Doctrine\ORM\EntityManagerInterface;
  16. use Doctrine\ORM\Query\Expr;
  17. use Doctrine\ORM\QueryBuilder;
  18. use PHPUnit\Framework\MockObject\MockObject;
  19. use PHPUnit\Framework\TestCase;
  20. use Psr\Log\LoggerInterface;
  21. use Symfony\Component\Config\Definition\Builder\ExprBuilder;
  22. class TestableCleanTempFile extends CleanTempFiles {
  23. public function listFilesToDelete(\DateTime $maxDate): array { return parent::listFilesToDelete($maxDate); }
  24. public function deleteFiles(array $files): void { parent::deleteFiles($files); }
  25. public function purgeDb(\DateTime $maxDate, bool $commit = true): void { parent::purgeDb($maxDate, $commit); }
  26. public function purgeFiles(\DateTime $maxDate): int { return parent::purgeFiles($maxDate); }
  27. public function getQueryConditions(QueryBuilder $queryBuilder, \DateTime $maxDate): void { parent::getQueryConditions($queryBuilder, $maxDate); }
  28. }
  29. class CleanTempFilesTest extends TestCase
  30. {
  31. private CronUIInterface|MockObject $ui;
  32. private MockObject|LoggerInterface $logger;
  33. private FileRepository|MockObject $fileRepository;
  34. private Connection|MockObject $connection;
  35. private LocalStorage|MockObject $storage;
  36. public function setUp(): void
  37. {
  38. $this->ui = $this->getMockBuilder(CronUIInterface::class)->disableOriginalConstructor()->getMock();
  39. $this->logger = $this->getMockBuilder(LoggerInterface::class)->disableOriginalConstructor()->getMock();
  40. $this->fileRepository = $this->getMockBuilder(FileRepository::class)->disableOriginalConstructor()->getMock();
  41. $this->connection = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock();
  42. $this->storage = $this->getMockBuilder(LocalStorage::class)->disableOriginalConstructor()->getMock();
  43. }
  44. private function getMockFor(string $method) {
  45. $cleanTempFiles = $this->getMockBuilder(TestableCleanTempFile::class)
  46. ->setConstructorArgs([$this->connection, $this->fileRepository, $this->storage])
  47. ->setMethodsExcept([$method, 'setUI', 'setLoggerInterface'])
  48. ->getMock();
  49. $cleanTempFiles->setUI($this->ui);
  50. $cleanTempFiles->setLoggerInterface($this->logger);
  51. return $cleanTempFiles;
  52. }
  53. public function testPreview(): void
  54. {
  55. DatesUtils::setFakeDatetime('2022-01-08 00:00:00');
  56. $maxDate = DatesUtils::new();
  57. $maxDate->sub(new \DateInterval('P60D'));
  58. $cleanTempFiles = $this->getMockFor('preview');
  59. $file1 = $this->getMockBuilder(File::class)->getMock();
  60. $file1->method('getPath')->willReturn('/foo');
  61. $file2 = $this->getMockBuilder(File::class)->getMock();
  62. $file2->method('getPath')->willReturn('/bar');
  63. $file3 = $this->getMockBuilder(File::class)->getMock();
  64. $file3->method('getPath')->willReturn('/foo/bar');
  65. $cleanTempFiles->method('listFilesToDelete')->with($maxDate)->willReturn([$file1, $file2, $file3]);
  66. $this->ui->expects(self::atLeastOnce())->method('print')->withConsecutive(
  67. ["3 temporary files to be removed"],
  68. ["> Printing the first and last 50 :"],
  69. [" * /foo"],
  70. [" * /bar"],
  71. [" * /foo/bar"]
  72. );
  73. $cleanTempFiles->expects(self::once())->method('purgeDb')->with($maxDate, false);
  74. $cleanTempFiles->preview();
  75. }
  76. public function testExecute(): void {
  77. DatesUtils::setFakeDatetime('2022-01-08 00:00:00');
  78. $maxDate = DatesUtils::new();
  79. $maxDate->sub(new \DateInterval('P60D'));
  80. $cleanTempFiles = $this->getMockFor('execute');
  81. $files = [
  82. $this->getMockBuilder(File::class)->getMock(),
  83. $this->getMockBuilder(File::class)->getMock(),
  84. $this->getMockBuilder(File::class)->getMock()
  85. ];
  86. $cleanTempFiles->method('listFilesToDelete')->willReturn($files)->with($maxDate);
  87. $cleanTempFiles->expects(self::once())->method('deleteFiles')->with($files);
  88. $cleanTempFiles->expects(self::once())->method('purgeDb')->with($maxDate);
  89. $cleanTempFiles->execute();
  90. }
  91. public function testListFilesToDelete()
  92. {
  93. $cleanTempFiles = $this->getMockFor('listFilesToDelete');
  94. DatesUtils::setFakeDatetime('2023-05-01 00:00:00');
  95. $maxDate = DatesUtils::new();
  96. // Mock la méthode getQueryBuilder()
  97. $queryBuilder = $this->getMockBuilder(QueryBuilder::class)
  98. ->disableOriginalConstructor()
  99. ->getMock();
  100. $this->fileRepository->method('createQueryBuilder')->with('f')->willReturn($queryBuilder);
  101. // S'attend à ce que la méthode select() soit appelée
  102. $queryBuilder->expects($this->once())
  103. ->method('select');
  104. // S'attend à ce que la méthode getQueryConditions() soit appelée avec $maxDate
  105. $cleanTempFiles->expects($this->once())
  106. ->method('getQueryConditions')
  107. ->with($queryBuilder, $maxDate);
  108. // Mock la méthode getQuery() et getResult() pour renvoyer un tableau vide
  109. $query = $this->getMockBuilder(AbstractQuery::class)
  110. ->disableOriginalConstructor()
  111. ->getMock();
  112. $query->expects($this->once())
  113. ->method('getResult')
  114. ->willReturn([]);
  115. $queryBuilder->expects($this->once())
  116. ->method('getQuery')
  117. ->willReturn($query);
  118. // Appeler la méthode listFilesToDelete()
  119. $result = $cleanTempFiles->listFilesToDelete($maxDate);
  120. // Vérifier que la méthode getResult() a été appelée sur la requête
  121. $this->assertEquals([], $result);
  122. }
  123. public function testPurgeDbCommitsTransactionIfCommitIsTrue(): void
  124. {
  125. $cleanTempFiles = $this->getMockFor('purgeDb');
  126. DatesUtils::setFakeDatetime('2022-01-08 00:00:00');
  127. $maxDate = new \DateTime('now');
  128. $this->connection->expects($this->once())
  129. ->method('beginTransaction');
  130. $this->connection->expects($this->once())
  131. ->method('setAutoCommit')
  132. ->with(false);
  133. $cleanTempFiles->method('purgeFiles')->willReturn(5)->with($maxDate);
  134. $this->connection->expects($this->once())
  135. ->method('commit');
  136. $this->ui->expects($this->once())
  137. ->method('print')
  138. ->with('DB purged - 5 records permanently deleted');
  139. $cleanTempFiles->purgeDb($maxDate);
  140. }
  141. public function testPurgeDbRollsbackTransactionIfCommitIsFalse(): void
  142. {
  143. $cleanTempFiles = $this->getMockFor('purgeDb');
  144. DatesUtils::setFakeDatetime('2022-01-08 00:00:00');
  145. $maxDate = DatesUtils::new();
  146. $this->connection->expects($this->once())
  147. ->method('beginTransaction');
  148. $this->connection->expects($this->once())
  149. ->method('setAutoCommit')
  150. ->with(false);
  151. $cleanTempFiles->method('purgeFiles')->willReturn(5)->with($maxDate);
  152. $this->connection->expects($this->once())
  153. ->method('rollback');
  154. $this->ui->expects($this->once())
  155. ->method('print')
  156. ->with('DB purged - 5 records would be permanently deleted');
  157. $cleanTempFiles->purgeDb($maxDate, false);
  158. }
  159. public function testPurgeDbRollsbackTransactionOnException(): void
  160. {
  161. $cleanTempFiles = $this->getMockFor('purgeDb');
  162. DatesUtils::setFakeDatetime('2022-01-08 00:00:00');
  163. $maxDate = DatesUtils::new();
  164. $cleanTempFiles->method('purgeFiles')->willThrowException(new \Exception('error'))->with($maxDate);
  165. $this->connection->expects($this->once())
  166. ->method('beginTransaction');
  167. $this->connection->expects($this->once())
  168. ->method('rollback');
  169. $this->ui->expects($this->never())
  170. ->method('print');
  171. $this->expectException(\Exception::class);
  172. $cleanTempFiles->purgeDb($maxDate, true);
  173. }
  174. public function testPurgeFilesDeletes()
  175. {
  176. $cleanTempFiles = $this->getMockFor('purgeFiles');
  177. DatesUtils::setFakeDatetime('2022-01-08 00:00:00');
  178. $maxDate = DatesUtils::new();
  179. $queryBuilder = $this->getMockBuilder(QueryBuilder::class)
  180. ->disableOriginalConstructor()
  181. ->getMock();
  182. $queryBuilder->expects($this->once())
  183. ->method('delete')
  184. ->willReturnSelf();
  185. $query = $this->getMockBuilder(AbstractQuery::class)
  186. ->disableOriginalConstructor()
  187. ->getMock();
  188. $queryBuilder->expects($this->once())
  189. ->method('getQuery')
  190. ->willReturn($query);
  191. $query->expects($this->once())
  192. ->method('execute')
  193. ->willReturn(3);
  194. $this->fileRepository->method('createQueryBuilder')->with('f')->willReturn($queryBuilder);
  195. $this->assertEquals(3, $cleanTempFiles->purgeFiles($maxDate));
  196. }
  197. }