Skip to content

Commit

Permalink
Added API-functional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rogyar committed May 8, 2019
1 parent 19b92cd commit 62e0530
Show file tree
Hide file tree
Showing 4 changed files with 384 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,17 @@ private function processCartItems(Quote $cart, array $items): void
if (!isset($item['quantity'])) {
throw new GraphQlInputException(__('Required parameter "quantity" for "cart_items" is missing.'));
}
$qty = (float)$item['quantity'];
$quantity = (float)$item['quantity'];

if ($qty <= 0.0) {
if ($quantity <= 0.0) {
$this->cartItemRepository->deleteById((int)$cart->getId(), $itemId);
} else {
$customizableOptions = $item['customizable_options'] ?? null;

if ($customizableOptions === null) { // Update only item's qty
$this->updateItemQty($itemId, $cart, $qty);
$this->updateItemQty($itemId, $cart, $quantity);
} else { // Update customizable options (and QTY if changed)
$this->updateCartItem->execute($cart, $itemId, $qty, $customizableOptions);
$this->updateCartItem->execute($cart, $itemId, $quantity, $customizableOptions);
$this->quoteRepository->save($cart);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\GraphQl\Quote;

use Magento\Catalog\Api\ProductCustomOptionRepositoryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException as NoSuchEntityException;
use Magento\Quote\Model\Quote\Item;
use Magento\Quote\Model\QuoteFactory;
use Magento\Quote\Model\ResourceModel\Quote as QuoteResource;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\TestCase\GraphQlAbstract;

/**
* Edit cart customizable options test
*/
class EditQuoteItemCustomOptionsTest extends GraphQlAbstract
{
/**
* @var ProductRepositoryInterface
*/
private $productRepository;

/**
* @var GetMaskedQuoteIdByReservedOrderId
*/
private $getMaskedQuoteIdByReservedOrderId;

/**
* @var ProductCustomOptionRepositoryInterface
*/
private $productCustomOptionsRepository;

/**
* @var QuoteFactory
*/
private $quoteFactory;

/**
* @var QuoteResource
*/
private $quoteResource;

/**
* @inheritdoc
*/
protected function setUp()
{
$objectManager = Bootstrap::getObjectManager();
$this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
$this->productCustomOptionsRepository = $objectManager->get(ProductCustomOptionRepositoryInterface::class);
$this->quoteFactory = $objectManager->get(QuoteFactory::class);
$this->quoteResource = $objectManager->get(QuoteResource::class);
$this->productRepository = $objectManager->get(ProductRepositoryInterface::class);
}

/**
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product_with_options.php
*/
public function testChangeQuoteItemCustomOptions()
{
$sku = 'simple_product';
$quoteItemId = $this->getQuoteItemIdBySku($sku);
$customOptionsValues = $this->getCustomOptionsValuesForQuery($sku);
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
$customizableOptionsQuery = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues));

$query = $this->getQuery($maskedQuoteId, $quoteItemId, $customizableOptionsQuery);
$response = $this->graphQlMutation($query);
$itemOptionsResponse = $response['updateCartItems']['cart']['items'][0]['customizable_options'];
self::assertCount(2, $itemOptionsResponse);
self::assertEquals('test', $itemOptionsResponse[0]['values'][0]['value']);
self::assertEquals('test', $itemOptionsResponse[1]['values'][0]['value']);
}

/**
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product_with_options.php
*/
public function testOptionsSetPersistsOnQtyChange()
{
$sku = 'simple_product';
$newQuantity = 2;
$quoteItemId = $this->getQuoteItemIdBySku($sku);
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');

$query = <<<QUERY
mutation {
updateCartItems(input: {
cart_id:"$maskedQuoteId"
cart_items: [
{
cart_item_id: $quoteItemId
quantity: $newQuantity
}
]
}) {
cart {
items {
quantity
... on SimpleCartItem {
customizable_options {
label
values {
value
}
}
}
}
}
}
}
QUERY;
$response = $this->graphQlMutation($query);
$cartItemResponse = $response['updateCartItems']['cart']['items'][0];

self::assertEquals($newQuantity, $cartItemResponse['quantity']);
self::assertCount(2, $cartItemResponse['customizable_options']);
self::assertEquals('initial value', $cartItemResponse['customizable_options'][0]['values'][0]['value']);
self::assertEquals('initial value', $cartItemResponse['customizable_options'][1]['values'][0]['value']);
}

/**
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product_with_options.php
*/
public function testOptionsSetChangedOnChangeOneOption()
{
$sku = 'simple_product';
$quoteItemId = $this->getQuoteItemIdBySku($sku);

/* Get only the first option */
$customOptionsValues = array_slice($this->getCustomOptionsValuesForQuery($sku), 0, 1);

$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
$customizableOptionsQuery = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues));
$query = $this->getQuery($maskedQuoteId, $quoteItemId, $customizableOptionsQuery);

$response = $this->graphQlMutation($query);
$itemOptionsResponse = $response['updateCartItems']['cart']['items'][0]['customizable_options'];
self::assertCount(1, $itemOptionsResponse);
self::assertEquals('test', $itemOptionsResponse[0]['values'][0]['value']);
}

/**
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product_with_options.php
* @group recent
*/
public function testOptionSetPersistsOnExtraOptionWithIncorrectId()
{
$sku = 'simple_product';
$quoteItemId = $this->getQuoteItemIdBySku($sku);
$customOptionsValues = $this->getCustomOptionsValuesForQuery($sku);

/* Add nonexistent option to the query */
$customOptionsValues[] = ['id' => -10, 'value' => 'value'];

$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
$customizableOptionsQuery = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues));
$query = $this->getQuery($maskedQuoteId, $quoteItemId, $customizableOptionsQuery);

$response = $this->graphQlMutation($query);
$itemOptionsResponse = $response['updateCartItems']['cart']['items'][0]['customizable_options'];
self::assertCount(2, $itemOptionsResponse);
}

/**
* Returns GraphQl query for updating items in shopping cart
*
* @param string $maskedQuoteId
* @param int $quoteItemId
* @param $customizableOptionsQuery
* @return string
*/
private function getQuery(string $maskedQuoteId, int $quoteItemId, $customizableOptionsQuery): string
{
return <<<QUERY
mutation {
updateCartItems(input: {
cart_id:"$maskedQuoteId"
cart_items: [
{
cart_item_id: $quoteItemId
quantity: 1
customizable_options: $customizableOptionsQuery
}
]
}) {
cart {
items {
quantity
product {
name
}
... on SimpleCartItem {
customizable_options {
label
values {
label
value
}
}
}
}
}
}
}
QUERY;
}

/**
* Returns quote item id by product's SKU
*
* @param string $sku
* @return int
* @throws NoSuchEntityException
*/
private function getQuoteItemIdBySku(string $sku): int
{
$quote = $this->quoteFactory->create();
$product = $this->productRepository->get($sku);
$this->quoteResource->load($quote, 'test_quote', 'reserved_order_id');
/** @var Item $quoteItem */
$quoteItem = $quote->getItemByProduct($product);

return (int)$quoteItem->getId();
}


/**
* Generate an array with test values for customizable options
* based on the option type
*
* @param string $sku
* @return array
*/
private function getCustomOptionsValuesForQuery(string $sku): array
{
$customOptions = $this->productCustomOptionsRepository->getList($sku);
$customOptionsValues = [];

foreach ($customOptions as $customOption) {
$optionType = $customOption->getType();
if ($optionType == 'field' || $optionType == 'area') {
$customOptionsValues[] = [
'id' => (int) $customOption->getOptionId(),
'value' => 'test'
];
} elseif ($optionType == 'drop_down') {
$optionSelectValues = $customOption->getValues();
$customOptionsValues[] = [
'id' => (int) $customOption->getOptionId(),
'value' => reset($optionSelectValues)->getOptionTypeId()
];
}
}

return $customOptionsValues;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

use Magento\Catalog\Api\Data\ProductCustomOptionInterface;
use Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\TestFramework\Helper\Bootstrap;

$objectManager = Bootstrap::getObjectManager();

$productCustomOptions = [];
$optionsSet = [
[
'title' => 'test_option_code_1',
'type' => 'field',
'is_require' => false,
'sort_order' => 1,
'price' => -10.0,
'price_type' => 'fixed',
'sku' => 'sku1',
'max_characters' => 100,
],
[
'title' => 'area option',
'type' => 'area',
'is_require' => false,
'sort_order' => 2,
'price' => 20.0,
'price_type' => 'percent',
'sku' => 'sku2',
'max_characters' => 100
]
];

/** @var ProductRepositoryInterface $productRepository */
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
$product = $productRepository->get('simple_product');
/** @var ProductCustomOptionInterfaceFactory $customOptionFactory */
$customOptionFactory = $objectManager->get(ProductCustomOptionInterfaceFactory::class);

foreach ($optionsSet as $option) {
/** @var ProductCustomOptionInterface $customOption */
$customOption = $customOptionFactory->create(['data' => $option]);
$customOption->setProductSku($product->getSku());

$productCustomOptions[] = $customOption;
}

$product->setOptions($productCustomOptions);
$productRepository->save($product);
Loading

0 comments on commit 62e0530

Please sign in to comment.