ProductUnitTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <?php
  2. namespace Tests\Unit\Products;
  3. use App\Shop\Categories\Category;
  4. use App\Shop\ProductImages\ProductImage;
  5. use App\Shop\ProductImages\ProductImageRepository;
  6. use App\Shop\Products\Exceptions\ProductCreateErrorException;
  7. use App\Shop\Products\Exceptions\ProductNotFoundException;
  8. use App\Shop\Products\Exceptions\ProductUpdateErrorException;
  9. use App\Shop\Products\Product;
  10. use App\Shop\Products\Repositories\ProductRepository;
  11. use Illuminate\Http\UploadedFile;
  12. use Illuminate\Support\Facades\Storage;
  13. use Tests\TestCase;
  14. class ProductUnitTest extends TestCase
  15. {
  16. /** @test */
  17. public function it_can_return_the_product_of_the_cover_image()
  18. {
  19. $thumbnails = [
  20. UploadedFile::fake()->image('cover.jpg', 600, 600),
  21. UploadedFile::fake()->image('cover.jpg', 600, 600),
  22. UploadedFile::fake()->image('cover.jpg', 600, 600)
  23. ];
  24. $collection = collect($thumbnails);
  25. $product = factory(Product::class)->create();
  26. $productRepo = new ProductRepository($product);
  27. $productRepo->saveProductImages($collection, $product);
  28. $images = $productRepo->findProductImages();
  29. $images->each(function (ProductImage $image) use ($product) {
  30. $productImageRepo = new ProductImageRepository($image);
  31. $foundProduct = $productImageRepo->findProduct();
  32. $this->assertInstanceOf(Product::class, $foundProduct);
  33. $this->assertEquals($product->name, $foundProduct->name);
  34. $this->assertEquals($product->slug, $foundProduct->slug);
  35. $this->assertEquals($product->description, $foundProduct->description);
  36. $this->assertEquals($product->quantity, $foundProduct->quantity);
  37. $this->assertEquals($product->price, $foundProduct->price);
  38. $this->assertEquals($product->status, $foundProduct->status);
  39. });
  40. }
  41. /** @test */
  42. public function it_can_save_the_thumbnails_properly_in_the_file_storage()
  43. {
  44. $thumbnails = [
  45. UploadedFile::fake()->image('cover.jpg', 600, 600),
  46. UploadedFile::fake()->image('cover.jpg', 600, 600),
  47. UploadedFile::fake()->image('cover.jpg', 600, 600)
  48. ];
  49. $collection = collect($thumbnails);
  50. $product = factory(Product::class)->create();
  51. $productRepo = new ProductRepository($product);
  52. $productRepo->saveProductImages($collection, $product);
  53. $images = $productRepo->findProductImages();
  54. $images->each(function (ProductImage $image) {
  55. $exists = Storage::disk('public')->exists($image->src);
  56. $this->assertTrue($exists);
  57. });
  58. }
  59. /** @test */
  60. public function it_can_save_the_cover_image_properly_in_file_storage()
  61. {
  62. $cover = UploadedFile::fake()->image('cover.jpg', 600, 600);
  63. $product = factory(Product::class)->create();
  64. $productRepo = new ProductRepository($product);
  65. $filename = $productRepo->saveCoverImage($cover);
  66. $exists = Storage::disk('public')->exists($filename);
  67. $this->assertTrue($exists);
  68. }
  69. /** @test */
  70. public function it_can_detach_all_the_categories()
  71. {
  72. $product = factory(Product::class)->create();
  73. $categories = factory(Category::class, 4)->create();
  74. $productRepo = new ProductRepository($product);
  75. $ids = $categories->transform(function (Category $category) {
  76. return $category->id;
  77. })->all();
  78. $productRepo->syncCategories($ids);
  79. $this->assertCount(4, $productRepo->getCategories());
  80. $productRepo->detachCategories();
  81. $this->assertCount(0, $productRepo->getCategories());
  82. }
  83. /** @test */
  84. public function it_can_delete_a_thumbnail_image()
  85. {
  86. $product = 'apple';
  87. $cover = UploadedFile::fake()->image('file.png', 600, 600);
  88. $params = [
  89. 'sku' => $this->faker->numberBetween(1111111, 999999),
  90. 'name' => $product,
  91. 'slug' => str_slug($product),
  92. 'description' => $this->faker->paragraph,
  93. 'cover' => $cover,
  94. 'quantity' => 10,
  95. 'price' => 9.95,
  96. 'status' => 1,
  97. 'image' => [
  98. UploadedFile::fake()->image('file.png', 200, 200),
  99. UploadedFile::fake()->image('file1.png', 200, 200),
  100. UploadedFile::fake()->image('file2.png', 200, 200)
  101. ]
  102. ];
  103. $productRepo = new ProductRepository(new Product);
  104. $created = $productRepo->createProduct($params);
  105. $repo = new ProductRepository($created);
  106. $repo->saveProductImages(collect($params['image']), $created);
  107. $thumbnails = $repo->findProductImages();
  108. $this->assertCount(3, $repo->findProductImages());
  109. $thumbnails->each(function ($thumbnail) {
  110. $repo = new ProductRepository(new Product());
  111. $repo->deleteThumb($thumbnail->src);
  112. });
  113. $this->assertCount(0, $repo->findProductImages());
  114. }
  115. /** @test */
  116. public function it_can_show_all_the_product_images()
  117. {
  118. $product = 'apple';
  119. $cover = UploadedFile::fake()->image('file.png', 600, 600);
  120. $params = [
  121. 'sku' => $this->faker->numberBetween(1111111, 999999),
  122. 'name' => $product,
  123. 'slug' => str_slug($product),
  124. 'description' => $this->faker->paragraph,
  125. 'cover' => $cover,
  126. 'quantity' => 10,
  127. 'price' => 9.95,
  128. 'status' => 1,
  129. 'image' => [
  130. UploadedFile::fake()->image('file.png', 200, 200),
  131. UploadedFile::fake()->image('file1.png', 200, 200),
  132. UploadedFile::fake()->image('file2.png', 200, 200)
  133. ]
  134. ];
  135. $productRepo = new ProductRepository(new Product);
  136. $created = $productRepo->createProduct($params);
  137. $repo = new ProductRepository($created);
  138. $repo->saveProductImages(collect($params['image']), $created);
  139. $this->assertCount(3, $repo->findProductImages());
  140. }
  141. /** @test */
  142. public function it_can_search_the_product()
  143. {
  144. $product = factory(Product::class)->create();
  145. $name = str_limit($product->name, 2, '');
  146. $productRepo = new ProductRepository($product);
  147. $results = $productRepo->searchProduct($name);
  148. $this->assertGreaterThan(0, $results->count());
  149. }
  150. /** @test */
  151. public function it_can_delete_the_file_only_by_updating_the_database()
  152. {
  153. $product = new ProductRepository($this->product);
  154. $this->assertTrue($product->deleteFile(['product' => $this->product->id]));
  155. }
  156. /** @test */
  157. public function it_errors_when_the_slug_in_not_found()
  158. {
  159. $this->expectException(ProductNotFoundException::class);
  160. $product = new ProductRepository($this->product);
  161. $product->findProductBySlug(['slug' => 'unknown']);
  162. }
  163. /** @test */
  164. public function it_can_find_the_product_with_the_slug()
  165. {
  166. $product = new ProductRepository($this->product);
  167. $found = $product->findProductBySlug(['slug' => $this->product->slug]);
  168. $this->assertEquals($this->product->name, $found->name);
  169. }
  170. /** @test */
  171. public function it_errors_updating_the_product_with_required_fields_are_not_passed()
  172. {
  173. $this->expectException(ProductUpdateErrorException::class);
  174. $product = new ProductRepository($this->product);
  175. $product->updateProduct(['name' => null]);
  176. }
  177. /** @test */
  178. public function it_errors_creating_the_product_when_required_fields_are_not_passed()
  179. {
  180. $this->expectException(ProductCreateErrorException::class);
  181. $product = new ProductRepository(new Product);
  182. $product->createProduct([]);
  183. }
  184. /** @test */
  185. public function it_can_delete_a_product()
  186. {
  187. $product = factory(Product::class)->create();
  188. $productRepo = new ProductRepository($product);
  189. $thumbnails = [
  190. UploadedFile::fake()->image('file.png', 200, 200),
  191. UploadedFile::fake()->image('file1.png', 200, 200),
  192. UploadedFile::fake()->image('file2.png', 200, 200)
  193. ];
  194. $productRepo->saveProductImages(collect($thumbnails));
  195. $deleted = $productRepo->removeProduct($product);
  196. $this->assertTrue($deleted);
  197. $this->assertDatabaseMissing('products', ['name' => $product->name]);
  198. }
  199. /** @test */
  200. public function it_can_list_all_the_products()
  201. {
  202. $product = factory(Product::class)->create();
  203. $attributes = $product->getFillable();
  204. $productRepo = new ProductRepository(new Product);
  205. $products = $productRepo->listProducts();
  206. $products->each(function ($product, $key) use ($attributes) {
  207. foreach ($product->getFillable() as $key => $value) {
  208. $this->assertArrayHasKey($key, $attributes);
  209. }
  210. });
  211. }
  212. /** @test */
  213. public function it_errors_finding_a_product()
  214. {
  215. $this->expectException(ProductNotFoundException::class);
  216. $product = new ProductRepository(new Product);
  217. $product->findProductById(999);
  218. }
  219. /** @test */
  220. public function it_can_find_the_product()
  221. {
  222. $product = new ProductRepository(new Product);
  223. $found = $product->findProductById($this->product->id);
  224. $this->assertInstanceOf(Product::class, $found);
  225. $this->assertEquals($this->product->sku, $found->sku);
  226. $this->assertEquals($this->product->name, $found->name);
  227. $this->assertEquals($this->product->slug, $found->slug);
  228. $this->assertEquals($this->product->description, $found->description);
  229. $this->assertEquals($this->product->quantity, $found->quantity);
  230. $this->assertEquals($this->product->price, $found->price);
  231. $this->assertEquals($this->product->status, $found->status);
  232. }
  233. /** @test */
  234. public function it_can_update_a_product()
  235. {
  236. $product = factory(Product::class)->create();
  237. $productName = 'apple';
  238. $cover = UploadedFile::fake()->image('file.png', 600, 600);
  239. $data = [
  240. 'sku' => '11111',
  241. 'name' => $productName,
  242. 'slug' => str_slug($productName),
  243. 'description' => $this->faker->paragraph,
  244. 'cover' => $cover,
  245. 'quantity' => 11,
  246. 'price' => 9.95,
  247. 'status' => 1
  248. ];
  249. $productRepo = new ProductRepository($product);
  250. $updated = $productRepo->updateProduct($data);
  251. $this->assertTrue($updated);
  252. }
  253. /** @test */
  254. public function it_can_create_a_product()
  255. {
  256. $product = 'apple';
  257. $cover = UploadedFile::fake()->image('file.png', 600, 600);
  258. $params = [
  259. 'sku' => $this->faker->numberBetween(1111111, 999999),
  260. 'name' => $product,
  261. 'slug' => str_slug($product),
  262. 'description' => $this->faker->paragraph,
  263. 'cover' => $cover,
  264. 'quantity' => 10,
  265. 'price' => 9.95,
  266. 'status' => 1,
  267. ];
  268. $product = new ProductRepository(new Product);
  269. $created = $product->createProduct($params);
  270. $this->assertInstanceOf(Product::class, $created);
  271. $this->assertEquals($params['sku'], $created->sku);
  272. $this->assertEquals($params['name'], $created->name);
  273. $this->assertEquals($params['slug'], $created->slug);
  274. $this->assertEquals($params['description'], $created->description);
  275. $this->assertEquals($params['cover'], $created->cover);
  276. $this->assertEquals($params['quantity'], $created->quantity);
  277. $this->assertEquals($params['price'], $created->price);
  278. $this->assertEquals($params['status'], $created->status);
  279. }
  280. }