LinkManagementTest.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\ConfigurableProduct\Test\Unit\Model;
  7. use Magento\ConfigurableProduct\Model\LinkManagement;
  8. use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
  9. /**
  10. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  11. */
  12. class LinkManagementTest extends \PHPUnit\Framework\TestCase
  13. {
  14. /**
  15. * @var \PHPUnit_Framework_MockObject_MockObject
  16. */
  17. protected $productRepository;
  18. /**
  19. * @var \PHPUnit_Framework_MockObject_MockObject
  20. */
  21. protected $productFactory;
  22. /**
  23. * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
  24. */
  25. protected $objectManagerHelper;
  26. /**
  27. * @var \PHPUnit_Framework_MockObject_MockObject
  28. */
  29. protected $configurableType;
  30. /**
  31. * @var LinkManagement
  32. */
  33. protected $object;
  34. /**
  35. * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Api\DataObjectHelper
  36. */
  37. protected $dataObjectHelperMock;
  38. protected function setUp()
  39. {
  40. $this->productRepository = $this->createMock(\Magento\Catalog\Api\ProductRepositoryInterface::class);
  41. $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
  42. $this->productFactory = $this->createPartialMock(
  43. \Magento\Catalog\Api\Data\ProductInterfaceFactory::class,
  44. ['create']
  45. );
  46. $this->dataObjectHelperMock = $this->getMockBuilder(\Magento\Framework\Api\DataObjectHelper::class)
  47. ->disableOriginalConstructor()
  48. ->getMock();
  49. $this->configurableType =
  50. $this->getMockBuilder(\Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable::class)
  51. ->disableOriginalConstructor()->getMock();
  52. $this->object = $this->objectManagerHelper->getObject(
  53. \Magento\ConfigurableProduct\Model\LinkManagement::class,
  54. [
  55. 'productRepository' => $this->productRepository,
  56. 'productFactory' => $this->productFactory,
  57. 'configurableType' => $this->configurableType,
  58. 'dataObjectHelper' => $this->dataObjectHelperMock,
  59. ]
  60. );
  61. }
  62. public function testGetChildren()
  63. {
  64. $productId = 'test';
  65. $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  66. ->disableOriginalConstructor()
  67. ->getMock();
  68. $productTypeInstance = $this->getMockBuilder(
  69. \Magento\ConfigurableProduct\Model\Product\Type\Configurable::class
  70. )->disableOriginalConstructor()->getMock();
  71. $product->expects($this->any())->method('getTypeId')->willReturn(Configurable::TYPE_CODE);
  72. $product->expects($this->any())->method('getStoreId')->willReturn(1);
  73. $product->expects($this->any())->method('getTypeInstance')->willReturn($productTypeInstance);
  74. $productTypeInstance->expects($this->once())->method('setStoreFilter')->with(1, $product);
  75. $childProduct = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  76. ->disableOriginalConstructor()
  77. ->getMock();
  78. $productTypeInstance->expects($this->any())->method('getUsedProducts')
  79. ->with($product)->willReturn([$childProduct]);
  80. $this->productRepository->expects($this->any())
  81. ->method('get')->with($productId)
  82. ->willReturn($product);
  83. $attribute = $this->createMock(\Magento\Eav\Api\Data\AttributeInterface::class);
  84. $attribute->expects($this->once())->method('getAttributeCode')->willReturn('code');
  85. $childProduct->expects($this->once())->method('getDataUsingMethod')->with('code')->willReturn(false);
  86. $childProduct->expects($this->once())->method('getData')->with('code')->willReturn(10);
  87. $childProduct->expects($this->once())->method('getStoreId')->willReturn(1);
  88. $childProduct->expects($this->once())->method('getAttributes')->willReturn([$attribute]);
  89. $productMock = $this->createMock(\Magento\Catalog\Api\Data\ProductInterface::class);
  90. $this->dataObjectHelperMock->expects($this->once())
  91. ->method('populateWithArray')
  92. ->with($productMock, ['store_id' => 1, 'code' => 10], \Magento\Catalog\Api\Data\ProductInterface::class)
  93. ->willReturnSelf();
  94. $this->productFactory->expects($this->once())
  95. ->method('create')
  96. ->willReturn($productMock);
  97. $products = $this->object->getChildren($productId);
  98. $this->assertCount(1, $products);
  99. $this->assertEquals($productMock, $products[0]);
  100. }
  101. public function testGetWithNonConfigurableProduct()
  102. {
  103. $productId= 'test';
  104. $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  105. ->disableOriginalConstructor()
  106. ->getMock();
  107. $product->expects($this->any())->method('getTypeId')->willReturn('simple');
  108. $this->productRepository->expects($this->any())
  109. ->method('get')->with($productId)
  110. ->willReturn($product);
  111. $this->assertEmpty($this->object->getChildren($productId));
  112. }
  113. public function testAddChild()
  114. {
  115. $productSku = 'configurable-sku';
  116. $childSku = 'simple-sku';
  117. $configurable = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  118. ->disableOriginalConstructor()
  119. ->setMethods(['getId', 'getExtensionAttributes'])
  120. ->getMock();
  121. $simple = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  122. ->disableOriginalConstructor()
  123. ->setMethods(['getId', 'getData'])
  124. ->getMock();
  125. $extensionAttributesMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductExtension::class)
  126. ->disableOriginalConstructor()
  127. ->setMethods([
  128. 'getConfigurableProductOptions', 'setConfigurableProductOptions', 'setConfigurableProductLinks'
  129. ])
  130. ->getMock();
  131. $optionMock = $this->getMockBuilder(\Magento\ConfigurableProduct\Api\Data\Option::class)
  132. ->disableOriginalConstructor()
  133. ->setMethods(['getProductAttribute', 'getAttributeId'])
  134. ->getMock();
  135. $productAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class)
  136. ->disableOriginalConstructor()
  137. ->setMethods(['getAttributeCode'])
  138. ->getMock();
  139. $optionsFactoryMock = $this->getMockBuilder(\Magento\ConfigurableProduct\Helper\Product\Options\Factory::class)
  140. ->disableOriginalConstructor()
  141. ->setMethods(['create'])
  142. ->getMock();
  143. $reflectionClass = new \ReflectionClass(\Magento\ConfigurableProduct\Model\LinkManagement::class);
  144. $optionsFactoryReflectionProperty = $reflectionClass->getProperty('optionsFactory');
  145. $optionsFactoryReflectionProperty->setAccessible(true);
  146. $optionsFactoryReflectionProperty->setValue($this->object, $optionsFactoryMock);
  147. $attributeFactoryMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory::class)
  148. ->disableOriginalConstructor()
  149. ->setMethods(['create'])
  150. ->getMock();
  151. $attributeFactoryReflectionProperty = $reflectionClass->getProperty('attributeFactory');
  152. $attributeFactoryReflectionProperty->setAccessible(true);
  153. $attributeFactoryReflectionProperty->setValue($this->object, $attributeFactoryMock);
  154. $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
  155. ->disableOriginalConstructor()
  156. ->setMethods(['getCollection', 'getOptions', 'getId', 'getAttributeCode', 'getStoreLabel'])
  157. ->getMock();
  158. $attributeOptionMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\Option::class)
  159. ->disableOriginalConstructor()
  160. ->setMethods(['getValue', 'getLabel'])
  161. ->getMock();
  162. $attributeCollectionMock = $this->getMockBuilder(
  163. \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection::class
  164. )
  165. ->disableOriginalConstructor()
  166. ->setMethods(['addFieldToFilter', 'getItems'])
  167. ->getMock();
  168. $this->productRepository->expects($this->at(0))->method('get')->with($productSku)->willReturn($configurable);
  169. $this->productRepository->expects($this->at(1))->method('get')->with($childSku)->willReturn($simple);
  170. $this->configurableType->expects($this->once())->method('getChildrenIds')->with(666)
  171. ->will(
  172. $this->returnValue([0 => [1, 2, 3]])
  173. );
  174. $configurable->expects($this->any())->method('getId')->will($this->returnValue(666));
  175. $simple->expects($this->any())->method('getId')->will($this->returnValue(999));
  176. $configurable->expects($this->any())->method('getExtensionAttributes')->willReturn($extensionAttributesMock);
  177. $extensionAttributesMock->expects($this->any())
  178. ->method('getConfigurableProductOptions')
  179. ->willReturn([$optionMock]);
  180. $optionMock->expects($this->any())->method('getProductAttribute')->willReturn($productAttributeMock);
  181. $productAttributeMock->expects($this->any())->method('getAttributeCode')->willReturn('color');
  182. $simple->expects($this->any())->method('getData')->willReturn('color');
  183. $optionMock->expects($this->any())->method('getAttributeId')->willReturn('1');
  184. $optionsFactoryMock->expects($this->any())->method('create')->willReturn([$optionMock]);
  185. $attributeFactoryMock->expects($this->any())->method('create')->willReturn($attributeMock);
  186. $attributeMock->expects($this->any())->method('getCollection')->willReturn($attributeCollectionMock);
  187. $attributeCollectionMock->expects($this->any())->method('addFieldToFilter')->willReturnSelf();
  188. $attributeCollectionMock->expects($this->any())->method('getItems')->willReturn([$attributeMock]);
  189. $attributeMock->expects($this->any())->method('getOptions')->willReturn([$attributeOptionMock]);
  190. $extensionAttributesMock->expects($this->any())->method('setConfigurableProductOptions');
  191. $extensionAttributesMock->expects($this->any())->method('setConfigurableProductLinks');
  192. $this->productRepository->expects($this->once())->method('save');
  193. $this->assertTrue(true, $this->object->addChild($productSku, $childSku));
  194. }
  195. /**
  196. * @expectedException \Magento\Framework\Exception\StateException
  197. * @expectedExceptionMessage The product is already attached.
  198. */
  199. public function testAddChildStateException()
  200. {
  201. $productSku = 'configurable-sku';
  202. $childSku = 'simple-sku';
  203. $configurable = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  204. ->disableOriginalConstructor()
  205. ->getMock();
  206. $configurable->expects($this->any())->method('getId')->will($this->returnValue(666));
  207. $simple = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  208. ->disableOriginalConstructor()
  209. ->getMock();
  210. $simple->expects($this->any())->method('getId')->will($this->returnValue(1));
  211. $this->productRepository->expects($this->at(0))->method('get')->with($productSku)->willReturn($configurable);
  212. $this->productRepository->expects($this->at(1))->method('get')->with($childSku)->willReturn($simple);
  213. $this->configurableType->expects($this->once())->method('getChildrenIds')->with(666)
  214. ->will(
  215. $this->returnValue([0 => [1, 2, 3]])
  216. );
  217. $configurable->expects($this->never())->method('save');
  218. $this->object->addChild($productSku, $childSku);
  219. }
  220. public function testRemoveChild()
  221. {
  222. $productSku = 'configurable';
  223. $childSku = 'simple_10';
  224. $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  225. ->setMethods(['getTypeInstance', 'save', 'getTypeId', 'addData', '__wakeup', 'getExtensionAttributes'])
  226. ->disableOriginalConstructor()
  227. ->getMock();
  228. $productType = $this->getMockBuilder(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::class)
  229. ->setMethods(['getUsedProducts'])
  230. ->disableOriginalConstructor()
  231. ->getMock();
  232. $product->expects($this->once())->method('getTypeInstance')->willReturn($productType);
  233. $product->expects($this->any())
  234. ->method('getTypeId')
  235. ->will($this->returnValue(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE));
  236. $this->productRepository->expects($this->any())
  237. ->method('get')
  238. ->with($productSku)
  239. ->will($this->returnValue($product));
  240. $option = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  241. ->setMethods(['getSku', 'getId', '__wakeup'])
  242. ->disableOriginalConstructor()
  243. ->getMock();
  244. $option->expects($this->any())->method('getSku')->will($this->returnValue($childSku));
  245. $option->expects($this->any())->method('getId')->will($this->returnValue(10));
  246. $productType->expects($this->once())->method('getUsedProducts')
  247. ->will($this->returnValue([$option]));
  248. $extensionAttributesMock = $this->getMockBuilder(\Magento\Framework\Api\ExtensionAttributesInterface::class)
  249. ->setMethods(['setConfigurableProductLinks'])
  250. ->disableOriginalConstructor()
  251. ->getMockForAbstractClass();
  252. $product->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributesMock);
  253. $this->productRepository->expects($this->once())->method('save');
  254. $this->assertTrue($this->object->removeChild($productSku, $childSku));
  255. }
  256. /**
  257. * @expectedException \Magento\Framework\Exception\InputException
  258. */
  259. public function testRemoveChildForbidden()
  260. {
  261. $productSku = 'configurable';
  262. $childSku = 'simple_10';
  263. $product = $this->createMock(\Magento\Catalog\Api\Data\ProductInterface::class);
  264. $product->expects($this->any())
  265. ->method('getTypeId')
  266. ->will($this->returnValue(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE));
  267. $this->productRepository->expects($this->any())->method('get')->will($this->returnValue($product));
  268. $this->object->removeChild($productSku, $childSku);
  269. }
  270. /**
  271. * @expectedException \Magento\Framework\Exception\NoSuchEntityException
  272. */
  273. public function testRemoveChildInvalidChildSku()
  274. {
  275. $productSku = 'configurable';
  276. $childSku = 'simple_10';
  277. $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  278. ->setMethods(['getTypeInstance', 'save', 'getTypeId', 'addData', '__wakeup'])
  279. ->disableOriginalConstructor()
  280. ->getMock();
  281. $product->expects($this->any())
  282. ->method('getTypeId')
  283. ->will($this->returnValue(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE));
  284. $productType = $this->getMockBuilder(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::class)
  285. ->setMethods(['getUsedProducts'])
  286. ->disableOriginalConstructor()
  287. ->getMock();
  288. $product->expects($this->once())->method('getTypeInstance')->willReturn($productType);
  289. $this->productRepository->expects($this->any())->method('get')->will($this->returnValue($product));
  290. $option = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
  291. ->setMethods(['getSku', 'getId', '__wakeup'])
  292. ->disableOriginalConstructor()
  293. ->getMock();
  294. $option->expects($this->any())->method('getSku')->will($this->returnValue($childSku . '_invalid'));
  295. $option->expects($this->any())->method('getId')->will($this->returnValue(10));
  296. $productType->expects($this->once())->method('getUsedProducts')
  297. ->will($this->returnValue([$option]));
  298. $this->object->removeChild($productSku, $childSku);
  299. }
  300. }