CleanupGeneratedDocumentsCommandTest.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <?php
  2. namespace Tests\Feature;
  3. use App\Models\File;
  4. use App\Models\Import;
  5. use App\Models\User;
  6. use Illuminate\Foundation\Testing\RefreshDatabase;
  7. use Illuminate\Support\Facades\Artisan;
  8. use Illuminate\Support\Facades\Storage;
  9. use Tests\TestCase;
  10. class CleanupGeneratedDocumentsCommandTest extends TestCase
  11. {
  12. use RefreshDatabase;
  13. public function test_cleanup_generated_documents_removes_only_old_generated_files(): void
  14. {
  15. Storage::fake('public');
  16. $user = User::factory()->create();
  17. $generated = File::factory()->create([
  18. 'user_id' => $user->id,
  19. 'original_name' => 'Монтаж тест.zip',
  20. 'mime_type' => 'application/zip',
  21. 'path' => 'orders/10/Монтаж тест.zip',
  22. 'link' => url('/storage/orders/10/Монтаж тест.zip'),
  23. 'is_generated' => true,
  24. 'created_at' => now()->subDays(15),
  25. 'updated_at' => now()->subDays(15),
  26. ]);
  27. $uploaded = File::factory()->create([
  28. 'user_id' => $user->id,
  29. 'original_name' => 'manual.zip',
  30. 'mime_type' => 'application/zip',
  31. 'path' => 'orders/10/document/manual.zip',
  32. 'link' => url('/storage/orders/10/document/manual.zip'),
  33. 'is_generated' => false,
  34. 'created_at' => now()->subDays(30),
  35. 'updated_at' => now()->subDays(30),
  36. ]);
  37. $freshGenerated = File::factory()->create([
  38. 'user_id' => $user->id,
  39. 'original_name' => 'Сдача свежий.zip',
  40. 'mime_type' => 'application/zip',
  41. 'path' => 'orders/11/Сдача свежий.zip',
  42. 'link' => url('/storage/orders/11/Сдача свежий.zip'),
  43. 'is_generated' => true,
  44. 'created_at' => now()->subDays(2),
  45. 'updated_at' => now()->subDays(2),
  46. ]);
  47. Storage::disk('public')->put($generated->path, 'generated');
  48. Storage::disk('public')->put($uploaded->path, 'uploaded');
  49. Storage::disk('public')->put($freshGenerated->path, 'fresh');
  50. $exitCode = Artisan::call('documents:cleanup-generated', ['--days' => 14]);
  51. $this->assertSame(0, $exitCode);
  52. $this->assertDatabaseMissing('files', ['id' => $generated->id]);
  53. $this->assertDatabaseHas('files', ['id' => $uploaded->id]);
  54. $this->assertDatabaseHas('files', ['id' => $freshGenerated->id]);
  55. Storage::disk('public')->assertMissing($generated->path);
  56. Storage::disk('public')->assertExists($uploaded->path);
  57. Storage::disk('public')->assertExists($freshGenerated->path);
  58. }
  59. public function test_cleanup_generated_documents_removes_legacy_tmp_archive_path(): void
  60. {
  61. Storage::fake('public');
  62. $user = User::factory()->create();
  63. $file = File::factory()->create([
  64. 'user_id' => $user->id,
  65. 'original_name' => 'Рекламация тест.zip',
  66. 'mime_type' => 'application/zip',
  67. 'path' => 'reclamations/20/tmp/Рекламация тест.zip',
  68. 'link' => url('/storage/reclamations/20/Рекламация тест.zip'),
  69. 'is_generated' => true,
  70. 'created_at' => now()->subDays(15),
  71. 'updated_at' => now()->subDays(15),
  72. ]);
  73. Storage::disk('public')->put('reclamations/20/Рекламация тест.zip', 'legacy archive');
  74. $exitCode = Artisan::call('documents:cleanup-generated', ['--days' => 14]);
  75. $this->assertSame(0, $exitCode);
  76. $this->assertDatabaseMissing('files', ['id' => $file->id]);
  77. Storage::disk('public')->assertMissing('reclamations/20/Рекламация тест.zip');
  78. }
  79. public function test_cleanup_removes_private_technical_description_export(): void
  80. {
  81. Storage::fake('public');
  82. Storage::fake('local');
  83. $user = User::factory()->create();
  84. $path = 'generated/technical-descriptions/'.$user->id.'/test/document.docx';
  85. $file = File::factory()->create([
  86. 'user_id' => $user->id,
  87. 'original_name' => 'document.docx',
  88. 'mime_type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  89. 'path' => $path,
  90. 'link' => route('common-catalog.technical-description.download', 1),
  91. 'is_generated' => true,
  92. 'created_at' => now()->subDays(15),
  93. 'updated_at' => now()->subDays(15),
  94. ]);
  95. Storage::disk('local')->put($path, 'generated');
  96. $exitCode = Artisan::call('documents:cleanup-generated', ['--days' => 14]);
  97. $this->assertSame(0, $exitCode);
  98. $this->assertDatabaseMissing('files', ['id' => $file->id]);
  99. Storage::disk('local')->assertMissing($path);
  100. }
  101. public function test_cleanup_generated_documents_removes_old_orphan_generated_archive(): void
  102. {
  103. Storage::fake('public');
  104. Storage::fake('upload');
  105. Storage::disk('public')->put('orders/15/Монтаж сирота.zip', 'orphan archive');
  106. touch(Storage::disk('public')->path('orders/15/Монтаж сирота.zip'), now()->subDays(20)->timestamp);
  107. Storage::disk('public')->put('orders/15/document/manual.zip', 'manual archive');
  108. touch(Storage::disk('public')->path('orders/15/document/manual.zip'), now()->subDays(20)->timestamp);
  109. $exitCode = Artisan::call('documents:cleanup-generated', ['--days' => 14]);
  110. $this->assertSame(0, $exitCode);
  111. Storage::disk('public')->assertMissing('orders/15/Монтаж сирота.zip');
  112. Storage::disk('public')->assertExists('orders/15/document/manual.zip');
  113. }
  114. public function test_cleanup_generated_documents_removes_old_import_files_and_orphans(): void
  115. {
  116. Storage::fake('public');
  117. Storage::fake('upload');
  118. $oldImport = Import::factory()->create([
  119. 'filename' => 'ab/old-import.xlsx',
  120. 'created_at' => now()->subDays(20),
  121. 'updated_at' => now()->subDays(20),
  122. ]);
  123. $freshImport = Import::factory()->create([
  124. 'filename' => 'cd/fresh-import.xlsx',
  125. 'created_at' => now()->subDays(2),
  126. 'updated_at' => now()->subDays(2),
  127. ]);
  128. Storage::disk('upload')->put($oldImport->filename, 'old import');
  129. Storage::disk('upload')->put($freshImport->filename, 'fresh import');
  130. Storage::disk('upload')->put('ef/orphan-import.xlsx', 'orphan import');
  131. touch(Storage::disk('upload')->path('ef/orphan-import.xlsx'), now()->subDays(20)->timestamp);
  132. $exitCode = Artisan::call('documents:cleanup-generated', [
  133. '--days' => 14,
  134. '--import-days' => 14,
  135. ]);
  136. $this->assertSame(0, $exitCode);
  137. Storage::disk('upload')->assertMissing($oldImport->filename);
  138. Storage::disk('upload')->assertExists($freshImport->filename);
  139. Storage::disk('upload')->assertMissing('ef/orphan-import.xlsx');
  140. }
  141. public function test_cleanup_generated_documents_removes_only_old_system_temp_zip_files(): void
  142. {
  143. Storage::fake('public');
  144. Storage::fake('upload');
  145. $tempDir = storage_path('framework/testing/tmp-cleanup');
  146. if (!is_dir($tempDir)) {
  147. mkdir($tempDir, 0777, true);
  148. }
  149. $oldZip = $tempDir . '/old-zip';
  150. $freshZip = $tempDir . '/fresh-zip';
  151. $oldText = $tempDir . '/old-text';
  152. file_put_contents($oldZip, "PK\x03\x04old");
  153. file_put_contents($freshZip, "PK\x03\x04fresh");
  154. file_put_contents($oldText, 'not zip');
  155. touch($oldZip, now()->subHours(2)->timestamp);
  156. touch($oldText, now()->subHours(2)->timestamp);
  157. config(['documents.temp_directory' => $tempDir]);
  158. try {
  159. $exitCode = Artisan::call('documents:cleanup-generated', [
  160. '--days' => 14,
  161. '--temp-hours' => 1,
  162. ]);
  163. $this->assertSame(0, $exitCode);
  164. $this->assertFileDoesNotExist($oldZip);
  165. $this->assertFileExists($freshZip);
  166. $this->assertFileExists($oldText);
  167. } finally {
  168. @unlink($oldZip);
  169. @unlink($freshZip);
  170. @unlink($oldText);
  171. @rmdir($tempDir);
  172. }
  173. }
  174. }