Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
BundleProductViewTest.php
Go to the documentation of this file.
1 <?php
6 declare(strict_types=1);
7 
9 
17 
19 {
20  const KEY_PRICE_TYPE_FIXED = 'FIXED';
21  const KEY_PRICE_TYPE_DYNAMIC = 'DYNAMIC';
22 
26  public function testAllFieldsBundleProducts()
27  {
28  $productSku = 'bundle-product';
29  $query
30  = <<<QUERY
31 {
32  products(filter: {sku: {eq: "{$productSku}"}})
33  {
34  items{
35  sku
36  type_id
37  id
38  name
39  attribute_set_id
40  ... on PhysicalProductInterface {
41  weight
42  }
43  ... on BundleProduct {
44  dynamic_sku
45  dynamic_price
46  dynamic_weight
47  price_view
48  ship_bundle_items
49  items {
50  option_id
51  title
52  required
53  type
54  position
55  sku
56  options {
57  id
58  qty
59  position
60  is_default
61  price
62  price_type
63  can_change_quantity
64  label
65  product {
66  id
67  name
68  sku
69  type_id
70  }
71  }
72  }
73  }
74  }
75  }
76 }
77 QUERY;
78 
79  $response = $this->graphQlQuery($query);
80 
82  $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
84  $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class);
85  $bundleProduct = $productRepository->get($productSku, false, null, true);
86  $bundleProduct->setId(
87  $bundleProduct->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField())
88  );
89  if ((bool)$bundleProduct->getShipmentType()) {
90  $this->assertEquals('SEPARATELY', $response['products']['items'][0]['ship_bundle_items']);
91  } else {
92  $this->assertEquals('TOGETHER', $response['products']['items'][0]['ship_bundle_items']);
93  }
94  if ((bool)$bundleProduct->getPriceView()) {
95  $this->assertEquals('AS_LOW_AS', $response['products']['items'][0]['price_view']);
96  } else {
97  $this->assertEquals('PRICE_RANGE', $response['products']['items'][0]['price_view']);
98  }
99  $this->assertBundleBaseFields($bundleProduct, $response['products']['items'][0]);
100 
101  $this->assertBundleProductOptions($bundleProduct, $response['products']['items'][0]);
102  $this->assertNotEmpty(
103  $response['products']['items'][0]['items'],
104  "Precondition failed: 'items' must not be empty"
105  );
106  }
107 
111  public function testBundleProdutWithNotVisibleChildren()
112  {
113  $productSku = 'bundle-product-1';
114  $query
115  = <<<QUERY
116 {
117  products(filter: {sku: {eq: "{$productSku}"}})
118  {
119  items{
120  sku
121  type_id
122  id
123  name
124  attribute_set_id
125  ... on PhysicalProductInterface {
126  weight
127  }
128  ... on BundleProduct {
129  dynamic_sku
130  dynamic_price
131  dynamic_weight
132  price_view
133  ship_bundle_items
134  items {
135  option_id
136  title
137  required
138  type
139  position
140  sku
141  options {
142  id
143  qty
144  position
145  is_default
146  price
147  price_type
148  can_change_quantity
149  label
150  product {
151  id
152  name
153  sku
154  type_id
155  }
156  }
157  }
158  }
159  }
160  }
161 }
162 QUERY;
163 
165  $config = ObjectManager::getInstance()->get(\Magento\Config\Model\ResourceModel\Config::class);
166  $config->saveConfig(
167  \Magento\CatalogInventory\Model\Configuration::XML_PATH_SHOW_OUT_OF_STOCK,
168  0,
170  0
171  );
172  ObjectManager::getInstance()->get(\Magento\Framework\App\Cache::class)
173  ->clean(\Magento\Framework\App\Config::CACHE_TAG);
174  $response = $this->graphQlQuery($query);
175  $this->assertNotEmpty(
176  $response['products']['items'],
177  "Precondition failed: 'items' must not be empty"
178  );
179 
181  $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
183  $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class);
184  $bundleProduct = $productRepository->get($productSku, false, null, true);
185  $bundleProduct->setId(
186  $bundleProduct->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField())
187  );
188  if ((bool)$bundleProduct->getShipmentType()) {
189  $this->assertEquals('SEPARATELY', $response['products']['items'][0]['ship_bundle_items']);
190  } else {
191  $this->assertEquals('TOGETHER', $response['products']['items'][0]['ship_bundle_items']);
192  }
193  if ((bool)$bundleProduct->getPriceView()) {
194  $this->assertEquals('AS_LOW_AS', $response['products']['items'][0]['price_view']);
195  } else {
196  $this->assertEquals('PRICE_RANGE', $response['products']['items'][0]['price_view']);
197  }
198  $this->assertBundleBaseFields($bundleProduct, $response['products']['items'][0]);
199 
200  $this->assertBundleProductOptions($bundleProduct, $response['products']['items'][0]);
201  $this->assertNotEmpty(
202  $response['products']['items'][0]['items'],
203  "Precondition failed: 'items' must not be empty"
204  );
205  }
206 
211  private function assertBundleBaseFields($product, $actualResponse)
212  {
213  $assertionMap = [
214  ['response_field' => 'sku', 'expected_value' => $product->getSku()],
215  ['response_field' => 'type_id', 'expected_value' => $product->getTypeId()],
216  ['response_field' => 'id', 'expected_value' => $product->getId()],
217  ['response_field' => 'name', 'expected_value' => $product->getName()],
218  ['response_field' => 'attribute_set_id', 'expected_value' => $product->getAttributeSetId()],
219  ['response_field' => 'weight', 'expected_value' => $product->getWeight()],
220  ['response_field' => 'dynamic_price', 'expected_value' => !(bool)$product->getPriceType()],
221  ['response_field' => 'dynamic_weight', 'expected_value' => !(bool)$product->getWeightType()],
222  ['response_field' => 'dynamic_sku', 'expected_value' => !(bool)$product->getSkuType()]
223  ];
224 
225  $this->assertResponseFields($actualResponse, $assertionMap);
226  }
227 
232  private function assertBundleProductOptions($product, $actualResponse)
233  {
234  $this->assertNotEmpty(
235  $actualResponse['items'],
236  "Precondition failed: 'bundle product items' must not be empty"
237  );
238  $metadataPool = ObjectManager::getInstance()->get(MetadataPool::class);
240  $optionList = ObjectManager::getInstance()->get(\Magento\Bundle\Model\Product\OptionList::class);
241  $options = $optionList->getItems($product);
242  $option = $options[0];
244  $bundleProductLinks = $option->getProductLinks();
245  $bundleProductLink = $bundleProductLinks[0];
246  $childProductSku = $bundleProductLink->getSku();
247  $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
248  $childProduct = $productRepository->get($childProductSku);
250  $childProduct->setId(
251  $childProduct->getData($metadataPool->getMetadata(ProductInterface::class)->getLinkField())
252  );
253  $this->assertEquals(1, count($options));
254  $this->assertResponseFields(
255  $actualResponse['items'][0],
256  [
257  'option_id' => $option->getOptionId(),
258  'title' => $option->getTitle(),
259  'required' =>(bool)$option->getRequired(),
260  'type' => $option->getType(),
261  'position' => $option->getPosition(),
262  'sku' => $option->getSku()
263  ]
264  );
265  $this->assertResponseFields(
266  $actualResponse['items'][0]['options'][0],
267  [
268  'id' => $bundleProductLink->getId(),
269  'qty' => (int)$bundleProductLink->getQty(),
270  'position' => $bundleProductLink->getPosition(),
271  'is_default' => (bool)$bundleProductLink->getIsDefault(),
272  'price_type' => self::KEY_PRICE_TYPE_FIXED,
273  'can_change_quantity' => $bundleProductLink->getCanChangeQuantity(),
274  'label' => $childProduct->getName()
275  ]
276  );
277  $this->assertResponseFields(
278  $actualResponse['items'][0]['options'][0]['product'],
279  [
280  'id' => $childProduct->getId(),
281  'name' => $childProduct->getName(),
282  'type_id' => $childProduct->getTypeId(),
283  'sku' => $bundleProductLink->getSku()
284  ]
285  );
286  }
287 
291  public function testAndMaxMinPriceBundleProduct()
292  {
293  $productSku = 'bundle-product';
294  $query
295  = <<<QUERY
296 {
297  products(filter: {sku: {eq: "{$productSku}"}})
298  {
299  items{
300  id
301  type_id
302  ... on PhysicalProductInterface {
303  weight
304  }
305  price {
306  minimalPrice {
307  amount {
308  value
309  currency
310  }
311  adjustments {
312  amount {
313  value
314  currency
315  }
316  code
317  description
318  }
319  }
320  maximalPrice {
321  amount {
322  value
323  currency
324  }
325  adjustments {
326  amount {
327  value
328  currency
329  }
330  code
331  description
332  }
333  }
334  regularPrice {
335  amount {
336  value
337  currency
338  }
339  adjustments {
340  amount {
341  value
342  currency
343  }
344  code
345  description
346  }
347  }
348  }
349  ... on BundleProduct {
350  dynamic_sku
351  dynamic_price
352  dynamic_weight
353  price_view
354  ship_bundle_items
355  items {
356  options {
357  label
358  product {
359  id
360  name
361  sku
362  }
363  }
364  }
365  }
366  }
367  }
368 }
369 QUERY;
370  $response = $this->graphQlQuery($query);
371 
373  $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
374  $bundleProduct = $productRepository->get($productSku, false, null, true);
376  $priceInfo = $bundleProduct->getPriceInfo();
378  $minimalPrice = $priceInfo->getPrice($priceCode)->getMinimalPrice()->getValue();
379  $maximalPrice = $priceInfo->getPrice($priceCode)->getMaximalPrice()->getValue();
380  $this->assertEquals(
382  $response['products']['items'][0]['price']['minimalPrice']['amount']['value']
383  );
384  $this->assertEquals(
386  $response['products']['items'][0]['price']['maximalPrice']['amount']['value']
387  );
388  }
389 
395  {
396  $productSku = 'bundle-product';
397  $query
398  = <<<QUERY
399 {
400  products(filter: {sku: {eq: "{$productSku}"}})
401  {
402  items{
403  id
404  type_id
405  qty
406  ... on PhysicalProductInterface {
407  weight
408  }
409 
410  ... on BundleProduct {
411  dynamic_sku
412  dynamic_price
413  dynamic_weight
414  price_view
415  ship_bundle_items
416  bundle_product_links {
417  id
418  name
419  sku
420  }
421  }
422  }
423  }
424 }
425 QUERY;
426 
427  $this->expectException(\Exception::class);
428  $this->expectExceptionMessage('GraphQL response contains errors: Cannot'. ' ' .
429  'query field "qty" on type "ProductInterface".');
430  $this->graphQlQuery($query);
431  }
432 }
$response
Definition: 404.php:11
$block setTitle( 'CMS Block Title') -> setIdentifier('fixture_block') ->setContent('< h1 >Fixture Block Title</h1 >< a href=" store url</a><p> Config value
Definition: block.php:9
if( $block->displayPriceExclTax()||$block->displayBothPrices())(__('Excl. Tax')) ?>"> <?php if ($block -> displayPriceWithWeeeDetails()): ?> <span class="cart-tax-total" data-mage-init=' Magento Weee Helper Data Magento Weee Helper Data title amount
Definition: unit.phtml:68
$config
Definition: fraud_order.php:17
$maximalPrice
assertResponseFields($actualResponse, $assertionMap)
taxRateField this edit on("click.mselect-delete", ".mselect-delete", function() { if(!confirm('<?=/*@escapeNotVerified */__( 'Do you really want to delete this tax rate?') ?>')) { return;} var that=$(this), select=that.closest('.mselect-list').prev(), rateValue=that.parent().find( 'input[type="checkbox"]').val();$( 'body').trigger( 'processStart');var ajaxOptions={ type:'POST', data:{ tax_calculation_rate_id:rateValue, form_key:$( 'input[name="form_key"]').val() }, dataType:'json', url:'<?=/*@escapeNotVerified */$block->getTaxRateDeleteUrl() ?>', success:function(result, status) { $( 'body').trigger( 'processStop');if(result.success) { that.parent().remove();select.find( 'option').each(function() { if(this.value===rateValue) { $(this).remove();} });select.trigger( 'change.hiddenSelect');} else { if(result.error_message) alert({ content:result.error_message });else alert({ content:'<?=/*@escapeNotVerified */__( 'An error occurred') ?>' });} }, error:function() { $( 'body').trigger( 'processStop');alert({ content:'<?=/*@escapeNotVerified */__( 'An error occurred') ?>' });} };$.ajax(ajaxOptions);}) .on( 'click.mselectAdd'
Definition: edit.phtml:164
$bundleProduct
graphQlQuery(string $query, array $variables=[], string $operationName='', array $headers=[])
$minimalPrice