Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ProductServiceTest.php
Go to the documentation of this file.
1 <?php
7 namespace Magento\Bundle\Api;
8 
14 
19 {
20  const SERVICE_NAME = 'catalogProductRepositoryV1';
21  const SERVICE_VERSION = 'V1';
22  const RESOURCE_PATH = '/V1/products';
23  const BUNDLE_PRODUCT_ID = 'sku-test-product-bundle';
24 
28  protected $productCollection;
29 
33  public function setUp()
34  {
36  $this->productCollection = $objectManager->get(\Magento\Catalog\Model\ResourceModel\Product\Collection::class);
37  }
38 
42  public function tearDown()
43  {
44  $this->deleteProductBySku(self::BUNDLE_PRODUCT_ID);
45  parent::tearDown();
46  }
47 
51  public function testCreateBundle()
52  {
53  $bundleProductOptions = [
54  [
55  "title" => "test option",
56  "type" => "checkbox",
57  "required" => true,
58  "product_links" => [
59  [
60  "sku" => 'simple',
61  "qty" => 1,
62  'is_default' => false,
63  'price' => 1.0,
64  'price_type' => LinkInterface::PRICE_TYPE_FIXED,
65  ],
66  ],
67  ],
68  ];
69 
70  $product = [
71  "sku" => self::BUNDLE_PRODUCT_ID,
72  "name" => self::BUNDLE_PRODUCT_ID,
73  "type_id" => "bundle",
74  "price" => 50,
75  'attribute_set_id' => 4,
76  "custom_attributes" => [
77  [
78  "attribute_code" => "price_type",
80  ],
81  [
82  "attribute_code" => "price_view",
83  "value" => 1,
84  ],
85  ],
86  "extension_attributes" => [
87  "bundle_product_options" => $bundleProductOptions,
88  ],
89  ];
90 
92 
93  $this->assertEquals(self::BUNDLE_PRODUCT_ID, $response[ProductInterface::SKU]);
94  $this->assertEquals(50, $response['price']);
95  $this->assertTrue(
96  isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["bundle_product_options"])
97  );
98  $resultBundleProductOptions
100  $this->assertTrue(isset($resultBundleProductOptions[0]["product_links"][0]["sku"]));
101  $this->assertEquals('simple', $resultBundleProductOptions[0]["product_links"][0]["sku"]);
102 
103  $response = $this->getProduct(self::BUNDLE_PRODUCT_ID);
104  $this->assertTrue(
105  isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["bundle_product_options"])
106  );
107  $resultBundleProductOptions
109  $this->assertTrue(isset($resultBundleProductOptions[0]["product_links"][0]["sku"]));
110  $this->assertEquals('simple', $resultBundleProductOptions[0]["product_links"][0]["sku"]);
111  }
112 
118  {
120  $bundleProductOptions = $this->getBundleProductOptions($bundleProduct);
121 
122  //Change the type of existing option
123  $bundleProductOptions[0]['type'] = 'select';
124  //Change the sku of existing link and qty
125  $bundleProductOptions[0]['product_links'][0]['sku'] = 'simple2';
126  $bundleProductOptions[0]['product_links'][0]['qty'] = 2;
127  $bundleProductOptions[0]['product_links'][0]['price'] = 10;
128  $bundleProductOptions[0]['product_links'][0]['price_type'] = 1;
129  $this->setBundleProductOptions($bundleProduct, $bundleProductOptions);
130 
131  $updatedProduct = $this->saveProduct($bundleProduct);
132 
133  $bundleOptions = $this->getBundleProductOptions($updatedProduct);
134  $this->assertEquals('select', $bundleOptions[0]['type']);
135  $this->assertEquals('simple2', $bundleOptions[0]['product_links'][0]['sku']);
136  $this->assertEquals(2, $bundleOptions[0]['product_links'][0]['qty']);
137  $this->assertEquals(10, $bundleOptions[0]['product_links'][0]['price']);
138  $this->assertEquals(1, $bundleOptions[0]['product_links'][0]['price_type']);
139  }
140 
146  {
148  $bundleProductOptions = $this->getBundleProductOptions($bundleProduct);
149 
150  //Change the type of existing option
151  $bundleProductOptions[0]['type'] = 'select';
152 
153  $this->setBundleProductOptions($bundleProduct, $bundleProductOptions);
154 
155  $updatedProduct = $this->saveProduct($bundleProduct);
156 
157  $bundleOptions = $this->getBundleProductOptions($updatedProduct);
158  $this->assertEquals('select', $bundleOptions[0]['type']);
159  $this->assertEquals('simple', $bundleOptions[0]['product_links'][0]['sku']);
160  $this->assertEquals(1, $bundleOptions[0]['product_links'][0]['qty']);
161  $this->assertEquals(20, $bundleOptions[0]['product_links'][0]['price']);
162  $this->assertEquals(1, $bundleOptions[0]['product_links'][0]['price_type']);
163  }
164 
170  {
172  $bundleProductOptions = $this->getBundleProductOptions($bundleProduct);
173 
174  $existingSelectionId = $bundleProductOptions[0]['product_links'][0]['id'];
175 
176  //unset bundle_product_options
177  unset($bundleProductOptions[0]['product_links']);
179 
180  $updatedProduct = $this->saveProduct($bundleProduct);
181 
182  $bundleOptions = $this->getBundleProductOptions($updatedProduct);
183  $this->assertEquals('checkbox', $bundleOptions[0]['type']);
184  $this->assertEquals('simple', $bundleOptions[0]['product_links'][0]['sku']);
185  $this->assertEquals(1, $bundleOptions[0]['product_links'][0]['qty']);
186  $this->assertEquals($existingSelectionId, $bundleOptions[0]['product_links'][0]['id']);
187  $this->assertEquals(20, $bundleOptions[0]['product_links'][0]['price']);
188  $this->assertEquals(1, $bundleOptions[0]['product_links'][0]['price_type']);
189  }
190 
196  {
198  $bundleProductOptions = $this->getBundleProductOptions($bundleProduct);
199 
200  //Add a selection to existing option
201  $bundleProductOptions[0]['product_links'][] = [
202  'sku' => 'simple2',
203  'qty' => 2,
204  "price" => 20,
205  "price_type" => 1,
206  "is_default" => false,
207  ];
208  $this->setBundleProductOptions($bundleProduct, $bundleProductOptions);
209  $updatedProduct = $this->saveProduct($bundleProduct);
210 
211  $bundleOptions = $this->getBundleProductOptions($updatedProduct);
212  $this->assertEquals('simple', $bundleOptions[0]['product_links'][0]['sku']);
213  $this->assertEquals('simple2', $bundleOptions[0]['product_links'][1]['sku']);
214  $this->assertEquals(2, $bundleOptions[0]['product_links'][1]['qty']);
215  $this->assertGreaterThan(
216  $bundleOptions[0]['product_links'][0]['id'],
217  $bundleOptions[0]['product_links'][1]['id']
218  );
219  }
220 
226  {
228 
229  $bundleProductOptions = $this->getBundleProductOptions($bundleProduct);
230 
231  $oldOptionId = $bundleProductOptions[0]['option_id'];
232  //replace current option with a new option
233  $bundleProductOptions[0] = [
234  'title' => 'new option',
235  'required' => true,
236  'type' => 'select',
237  'product_links' => [
238  [
239  'sku' => 'simple2',
240  'qty' => 2,
241  "price" => 20,
242  "price_type" => 1,
243  "is_default" => false,
244  ],
245  ],
246  ];
247  $this->setBundleProductOptions($bundleProduct, $bundleProductOptions);
248  $this->saveProduct($bundleProduct);
249 
250  $updatedProduct = $this->getProduct(self::BUNDLE_PRODUCT_ID);
251  $bundleOptions = $this->getBundleProductOptions($updatedProduct);
252  $this->assertEquals('new option', $bundleOptions[0]['title']);
253  $this->assertTrue($bundleOptions[0]['required']);
254  $this->assertEquals('select', $bundleOptions[0]['type']);
255  $this->assertGreaterThan($oldOptionId, $bundleOptions[0]['option_id']);
256  $this->assertFalse(isset($bundleOptions[1]));
257  $this->assertEquals('simple2', $bundleOptions[0]['product_links'][0]['sku']);
258  $this->assertEquals(2, $bundleOptions[0]['product_links'][0]['qty']);
259  }
260 
267  protected function getBundleProductOptions($product)
268  {
269  if (isset($product[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["bundle_product_options"])) {
270  return $product[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["bundle_product_options"];
271  } else {
272  return null;
273  }
274  }
275 
282  protected function setBundleProductOptions(&$product, $bundleProductOptions)
283  {
284  $product["extension_attributes"]["bundle_product_options"] = $bundleProductOptions;
285  return;
286  }
287 
293  protected function createDynamicBundleProduct()
294  {
295  $bundleProductOptions = [
296  [
297  "title" => "test option",
298  "type" => "checkbox",
299  "required" => 1,
300  "product_links" => [
301  [
302  "sku" => 'simple',
303  "qty" => 1,
304  "is_default" => true,
305  "price" => 10,
306  "price_type" => 1,
307  ],
308  ],
309  ],
310  ];
311 
312  $uniqueId = self::BUNDLE_PRODUCT_ID;
313  $product = [
314  "sku" => $uniqueId,
315  "name" => $uniqueId,
316  "type_id" => "bundle",
317  'attribute_set_id' => 4,
318  "custom_attributes" => [
319  "price_type" => [
320  'attribute_code' => 'price_type',
322  ],
323  "price_view" => [
324  "attribute_code" => "price_view",
325  "value" => "1",
326  ],
327  ],
328  "extension_attributes" => [
329  "bundle_product_options" => $bundleProductOptions,
330  ],
331  ];
332 
333  $response = $this->createProduct($product);
334  $this->assertTrue(
335  isset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["bundle_product_options"])
336  );
337  $resultBundleProductOptions
339  $this->assertTrue(isset($resultBundleProductOptions[0]["product_links"][0]["sku"]));
340  $this->assertEquals('simple', $resultBundleProductOptions[0]["product_links"][0]["sku"]);
341  $this->assertTrue(isset($response['custom_attributes']));
342  $customAttributes = $this->convertCustomAttributes($response['custom_attributes']);
343  $this->assertTrue(isset($customAttributes['price_type']));
344  $this->assertEquals(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC, $customAttributes['price_type']);
345  $this->assertTrue(isset($customAttributes['price_view']));
346  $this->assertEquals(1, $customAttributes['price_view']);
347  return $response;
348  }
349 
355  protected function createFixedPriceBundleProduct()
356  {
357  $bundleProductOptions = [
358  [
359  "title" => "test option",
360  "type" => "checkbox",
361  "required" => 1,
362  "product_links" => [
363  [
364  "sku" => 'simple',
365  "qty" => 1,
366  "price" => 20,
367  "price_type" => 1,
368  "is_default" => true,
369  ],
370  ],
371  ],
372  ];
373 
374  $uniqueId = self::BUNDLE_PRODUCT_ID;
375  $product = [
376  "sku" => $uniqueId,
377  "name" => $uniqueId,
378  "type_id" => "bundle",
379  "price" => 50,
380  'attribute_set_id' => 4,
381  "custom_attributes" => [
382  "price_type" => [
383  'attribute_code' => 'price_type',
385  ],
386  "price_view" => [
387  "attribute_code" => "price_view",
388  "value" => "1",
389  ],
390  ],
391  "extension_attributes" => [
392  "bundle_product_options" => $bundleProductOptions,
393  ],
394  ];
395 
396  $response = $this->createProduct($product);
397  $resultBundleProductOptions
399  $this->assertEquals('simple', $resultBundleProductOptions[0]["product_links"][0]["sku"]);
400  $this->assertTrue(isset($response['custom_attributes']));
401  $customAttributes = $this->convertCustomAttributes($response['custom_attributes']);
402  $this->assertTrue(isset($customAttributes['price_type']));
403  $this->assertEquals(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_FIXED, $customAttributes['price_type']);
404  $this->assertTrue(isset($customAttributes['price_view']));
405  $this->assertEquals(1, $customAttributes['price_view']);
406  return $response;
407  }
408 
409  protected function convertCustomAttributes($customAttributes)
410  {
411  $convertedCustomAttribute = [];
412  foreach ($customAttributes as $customAttribute) {
413  $convertedCustomAttribute[$customAttribute['attribute_code']] = $customAttribute['value'];
414  }
415  return $convertedCustomAttribute;
416  }
417 
424  protected function getProduct($productSku)
425  {
426  $serviceInfo = [
427  'rest' => [
428  'resourcePath' => self::RESOURCE_PATH . '/' . $productSku,
430  ],
431  'soap' => [
432  'service' => self::SERVICE_NAME,
433  'serviceVersion' => self::SERVICE_VERSION,
434  'operation' => self::SERVICE_NAME . 'Get',
435  ],
436  ];
437 
438  $response = (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) ?
439  $this->_webApiCall($serviceInfo, ['sku' => $productSku]) : $this->_webApiCall($serviceInfo);
440 
441  return $response;
442  }
443 
450  protected function createProduct($product)
451  {
452  $serviceInfo = [
453  'rest' => [
454  'resourcePath' => self::RESOURCE_PATH,
456  ],
457  'soap' => [
458  'service' => self::SERVICE_NAME,
459  'serviceVersion' => self::SERVICE_VERSION,
460  'operation' => self::SERVICE_NAME . 'Save',
461  ],
462  ];
463  $requestData = ['product' => $product];
464  $response = $this->_webApiCall($serviceInfo, $requestData);
465  return $response;
466  }
467 
474  protected function deleteProductBySku($productSku)
475  {
476  $resourcePath = self::RESOURCE_PATH . '/' . $productSku;
477  $serviceInfo = [
478  'rest' => [
479  'resourcePath' => $resourcePath,
481  ],
482  'soap' => [
483  'service' => self::SERVICE_NAME,
484  'serviceVersion' => self::SERVICE_VERSION,
485  'operation' => self::SERVICE_NAME . 'deleteById',
486  ],
487  ];
488  $requestData = ["sku" => $productSku];
489  $response = $this->_webApiCall($serviceInfo, $requestData);
490  return $response;
491  }
492 
499  protected function saveProduct($product)
500  {
501  if (isset($product['custom_attributes'])) {
502  for ($i=0; $i<sizeof($product['custom_attributes']); $i++) {
503  if ($product['custom_attributes'][$i]['attribute_code'] == 'category_ids'
504  && !is_array($product['custom_attributes'][$i]['value'])
505  ) {
506  $product['custom_attributes'][$i]['value'] = [""];
507  }
508  }
509  }
510  $resourcePath = self::RESOURCE_PATH . '/' . $product['sku'];
511  $serviceInfo = [
512  'rest' => [
513  'resourcePath' => $resourcePath,
515  ],
516  'soap' => [
517  'service' => self::SERVICE_NAME,
518  'serviceVersion' => self::SERVICE_VERSION,
519  'operation' => self::SERVICE_NAME . 'Save',
520  ],
521  ];
522  $requestData = ['product' => $product];
523  $response = $this->_webApiCall($serviceInfo, $requestData);
524  return $response;
525  }
526 }
$response
Definition: 404.php:11
$objectManager
Definition: bootstrap.php:17
_webApiCall( $serviceInfo, $arguments=[], $webApiAdapterCode=null, $storeCode=null, $integration=null)
setBundleProductOptions(&$product, $bundleProductOptions)
$bundleProduct
$i
Definition: gallery.phtml:31