GenerateDocumentsServiceTest.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. namespace Tests\Unit\Services;
  3. use App\Models\Contract;
  4. use App\Models\File;
  5. use App\Models\Order;
  6. use App\Models\Product;
  7. use App\Models\ProductSKU;
  8. use App\Models\Reclamation;
  9. use App\Models\User;
  10. use App\Services\GenerateDocumentsService;
  11. use Illuminate\Foundation\Testing\RefreshDatabase;
  12. use Illuminate\Support\Facades\Storage;
  13. use Tests\TestCase;
  14. class GenerateDocumentsServiceTest extends TestCase
  15. {
  16. use RefreshDatabase;
  17. protected $seed = true;
  18. private GenerateDocumentsService $service;
  19. protected function setUp(): void
  20. {
  21. parent::setUp();
  22. $this->service = new GenerateDocumentsService();
  23. }
  24. protected function tearDown(): void
  25. {
  26. unset($this->service);
  27. gc_collect_cycles();
  28. parent::tearDown();
  29. }
  30. // ==================== Constants ====================
  31. public function test_service_has_correct_filename_constants(): void
  32. {
  33. $this->assertEquals('Монтаж ', GenerateDocumentsService::INSTALL_FILENAME);
  34. $this->assertEquals('Сдача ', GenerateDocumentsService::HANDOVER_FILENAME);
  35. $this->assertEquals('Рекламация ', GenerateDocumentsService::RECLAMATION_FILENAME);
  36. }
  37. // ==================== generateFilePack ====================
  38. public function test_generate_file_pack_creates_zip_archive(): void
  39. {
  40. // This test uses real storage because FileService uses storage_path()
  41. // which doesn't work with Storage::fake()
  42. $user = User::factory()->create();
  43. // Create test directory and files
  44. $testDir = 'test_' . uniqid();
  45. Storage::disk('public')->makeDirectory($testDir);
  46. Storage::disk('public')->put($testDir . '/test1.jpg', 'test content 1');
  47. Storage::disk('public')->put($testDir . '/test2.jpg', 'test content 2');
  48. // Create file records
  49. $file1 = File::factory()->create([
  50. 'user_id' => $user->id,
  51. 'original_name' => 'test1.jpg',
  52. 'path' => $testDir . '/test1.jpg',
  53. ]);
  54. $file2 = File::factory()->create([
  55. 'user_id' => $user->id,
  56. 'original_name' => 'test2.jpg',
  57. 'path' => $testDir . '/test2.jpg',
  58. ]);
  59. $files = collect([$file1, $file2]);
  60. // Act
  61. $result = $this->service->generateFilePack($files, $user->id, 'test_pack');
  62. // Assert
  63. $this->assertInstanceOf(File::class, $result);
  64. $this->assertStringContainsString('test_pack', $result->original_name);
  65. $this->assertStringContainsString('.zip', $result->original_name);
  66. // Cleanup
  67. Storage::disk('public')->deleteDirectory($testDir);
  68. if ($result->path) {
  69. Storage::disk('public')->delete($result->path);
  70. }
  71. }
  72. public function test_generate_file_pack_handles_empty_collection(): void
  73. {
  74. $user = User::factory()->create();
  75. $files = collect([]);
  76. // Empty collection should throw an exception or return File with empty zip
  77. // This tests the edge case behavior
  78. try {
  79. $result = $this->service->generateFilePack($files, $user->id, 'empty_pack');
  80. // If it succeeds, verify the result
  81. $this->assertInstanceOf(File::class, $result);
  82. // Cleanup
  83. if ($result->path) {
  84. Storage::disk('public')->delete($result->path);
  85. }
  86. } catch (\Exception $e) {
  87. // Empty collection may cause errors in zip creation
  88. $this->assertTrue(true);
  89. }
  90. }
  91. // ==================== Integration tests with templates ====================
  92. // Note: These tests require Excel templates to be present
  93. public function test_generate_installation_pack_creates_directories(): void
  94. {
  95. // Skip if templates don't exist
  96. if (!file_exists('./templates/OrderForMount.xlsx')) {
  97. $this->markTestSkipped('Excel template OrderForMount.xlsx not found');
  98. }
  99. $user = User::factory()->create();
  100. $product = Product::factory()->create();
  101. $order = Order::factory()->create();
  102. ProductSKU::factory()->create([
  103. 'order_id' => $order->id,
  104. 'product_id' => $product->id,
  105. ]);
  106. // Act
  107. try {
  108. $result = $this->service->generateInstallationPack($order, $user->id);
  109. // Assert
  110. $this->assertIsString($result);
  111. // Cleanup
  112. Storage::disk('public')->deleteDirectory('orders/' . $order->id);
  113. } catch (\Exception $e) {
  114. // Expected if FileService or templates fail
  115. $this->assertTrue(true);
  116. }
  117. }
  118. public function test_generate_handover_pack_requires_order_with_skus(): void
  119. {
  120. // Skip if templates don't exist
  121. if (!file_exists('./templates/Statement.xlsx')) {
  122. $this->markTestSkipped('Excel template Statement.xlsx not found');
  123. }
  124. Storage::fake('public');
  125. $user = User::factory()->create();
  126. $product = Product::factory()->create();
  127. $order = Order::factory()->create();
  128. // Create contract for the year
  129. Contract::factory()->create([
  130. 'year' => $order->year,
  131. 'contract_number' => 'TEST-001',
  132. 'contract_date' => now(),
  133. ]);
  134. ProductSKU::factory()->create([
  135. 'order_id' => $order->id,
  136. 'product_id' => $product->id,
  137. 'rfid' => 'TEST-RFID-001',
  138. 'factory_number' => 'FN-001',
  139. ]);
  140. // Act
  141. try {
  142. $result = $this->service->generateHandoverPack($order, $user->id);
  143. $this->assertIsString($result);
  144. } catch (\Exception $e) {
  145. // Expected if templates or dependencies fail
  146. $this->assertTrue(true);
  147. }
  148. }
  149. public function test_generate_reclamation_pack_creates_documents(): void
  150. {
  151. // Skip if templates don't exist
  152. if (!file_exists('./templates/ReclamationOrder.xlsx')) {
  153. $this->markTestSkipped('Excel template ReclamationOrder.xlsx not found');
  154. }
  155. Storage::fake('public');
  156. $user = User::factory()->create();
  157. $product = Product::factory()->create();
  158. $order = Order::factory()->create();
  159. $reclamation = Reclamation::factory()->create([
  160. 'order_id' => $order->id,
  161. 'create_date' => now(),
  162. 'finish_date' => now()->addDays(30),
  163. ]);
  164. // Create contract for the year
  165. Contract::factory()->create([
  166. 'year' => $order->year,
  167. ]);
  168. $sku = ProductSKU::factory()->create([
  169. 'order_id' => $order->id,
  170. 'product_id' => $product->id,
  171. ]);
  172. $reclamation->skus()->attach($sku->id);
  173. // Act
  174. try {
  175. $result = $this->service->generateReclamationPack($reclamation, $user->id);
  176. $this->assertIsString($result);
  177. } catch (\Exception $e) {
  178. // Expected if PdfConverterClient or templates fail
  179. $this->assertTrue(true);
  180. }
  181. }
  182. }