CleanTempFilesTest.php 9.4 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): Collection { return parent::listFilesToDelete($maxDate); }
  24. public function deleteFiles(Collection $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(new ArrayCollection([$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 = new ArrayCollection([
  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(new ArrayCollection());
  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->assertInstanceOf(Collection::class, $result);
  122. $this->assertEquals(0, $result->count());
  123. }
  124. public function testPurgeDbCommitsTransactionIfCommitIsTrue(): void
  125. {
  126. $cleanTempFiles = $this->getMockFor('purgeDb');
  127. DatesUtils::setFakeDatetime('2022-01-08 00:00:00');
  128. $maxDate = new \DateTime('now');
  129. $this->connection->expects($this->once())
  130. ->method('beginTransaction');
  131. $this->connection->expects($this->once())
  132. ->method('setAutoCommit')
  133. ->with(false);
  134. $cleanTempFiles->method('purgeFiles')->willReturn(5)->with($maxDate);
  135. $this->connection->expects($this->once())
  136. ->method('commit');
  137. $this->ui->expects($this->once())
  138. ->method('print')
  139. ->with('DB purged - 5 records permanently deleted');
  140. $cleanTempFiles->purgeDb($maxDate);
  141. }
  142. public function testPurgeDbRollsbackTransactionIfCommitIsFalse(): void
  143. {
  144. $cleanTempFiles = $this->getMockFor('purgeDb');
  145. DatesUtils::setFakeDatetime('2022-01-08 00:00:00');
  146. $maxDate = DatesUtils::new();
  147. $this->connection->expects($this->once())
  148. ->method('beginTransaction');
  149. $this->connection->expects($this->once())
  150. ->method('setAutoCommit')
  151. ->with(false);
  152. $cleanTempFiles->method('purgeFiles')->willReturn(5)->with($maxDate);
  153. $this->connection->expects($this->once())
  154. ->method('rollback');
  155. $this->ui->expects($this->once())
  156. ->method('print')
  157. ->with('DB purged - 5 records would be permanently deleted');
  158. $cleanTempFiles->purgeDb($maxDate, false);
  159. }
  160. public function testPurgeDbRollsbackTransactionOnException(): void
  161. {
  162. $cleanTempFiles = $this->getMockFor('purgeDb');
  163. DatesUtils::setFakeDatetime('2022-01-08 00:00:00');
  164. $maxDate = DatesUtils::new();
  165. $cleanTempFiles->method('purgeFiles')->willThrowException(new \Exception('error'))->with($maxDate);
  166. $this->connection->expects($this->once())
  167. ->method('beginTransaction');
  168. $this->connection->expects($this->once())
  169. ->method('rollback');
  170. $this->ui->expects($this->never())
  171. ->method('print');
  172. $this->expectException(\Exception::class);
  173. $cleanTempFiles->purgeDb($maxDate, true);
  174. }
  175. public function testPurgeFilesDeletes()
  176. {
  177. $cleanTempFiles = $this->getMockFor('purgeFiles');
  178. DatesUtils::setFakeDatetime('2022-01-08 00:00:00');
  179. $maxDate = DatesUtils::new();
  180. $queryBuilder = $this->getMockBuilder(QueryBuilder::class)
  181. ->disableOriginalConstructor()
  182. ->getMock();
  183. $queryBuilder->expects($this->once())
  184. ->method('delete')
  185. ->willReturnSelf();
  186. $query = $this->getMockBuilder(AbstractQuery::class)
  187. ->disableOriginalConstructor()
  188. ->getMock();
  189. $queryBuilder->expects($this->once())
  190. ->method('getQuery')
  191. ->willReturn($query);
  192. $query->expects($this->once())
  193. ->method('execute')
  194. ->willReturn(3);
  195. $this->fileRepository->method('createQueryBuilder')->with('f')->willReturn($queryBuilder);
  196. $this->assertEquals(3, $cleanTempFiles->purgeFiles($maxDate));
  197. }
  198. }