Skip to content

Commit

Permalink
GraphQL-474: Cannot return null for non-nullable field SelectedCustom…
Browse files Browse the repository at this point in the history
…izableOptionValue.sort_order and Call to a member function getPriceType() on null
  • Loading branch information
naydav committed Apr 30, 2019
1 parent 733ddf9 commit 1315577
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 125 deletions.
52 changes: 23 additions & 29 deletions app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,13 @@
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\Quote\Model\Quote;

/**
* Add simple product to cart
*
* TODO: should be replaced for different types resolver
*/
class AddSimpleProductToCart
{
/**
* @var ArrayManager
*/
private $arrayManager;

/**
* @var DataObjectFactory
*/
Expand All @@ -39,16 +31,13 @@ class AddSimpleProductToCart
private $productRepository;

/**
* @param ArrayManager $arrayManager
* @param DataObjectFactory $dataObjectFactory
* @param ProductRepositoryInterface $productRepository
*/
public function __construct(
ArrayManager $arrayManager,
DataObjectFactory $dataObjectFactory,
ProductRepositoryInterface $productRepository
) {
$this->arrayManager = $arrayManager;
$this->dataObjectFactory = $dataObjectFactory;
$this->productRepository = $productRepository;
}
Expand All @@ -67,11 +56,6 @@ public function execute(Quote $cart, array $cartItemData): void
{
$sku = $this->extractSku($cartItemData);
$quantity = $this->extractQuantity($cartItemData);
if ($quantity <= 0) {
throw new GraphQlInputException(
__('Please enter a number greater than 0 in this field.')
);
}
$customizableOptions = $this->extractCustomizableOptions($cartItemData);

try {
Expand Down Expand Up @@ -105,11 +89,10 @@ public function execute(Quote $cart, array $cartItemData): void
*/
private function extractSku(array $cartItemData): string
{
$sku = $this->arrayManager->get('data/sku', $cartItemData);
if (!isset($sku)) {
throw new GraphQlInputException(__('Missing key "sku" in cart item data'));
if (!isset($cartItemData['data']['sku']) || empty($cartItemData['data']['sku'])) {
throw new GraphQlInputException(__('Missed "sku" in cart item data'));
}
return (string)$sku;
return (string)$cartItemData['data']['sku'];
}

/**
Expand All @@ -121,11 +104,17 @@ private function extractSku(array $cartItemData): string
*/
private function extractQuantity(array $cartItemData): float
{
$quantity = $this->arrayManager->get('data/quantity', $cartItemData);
if (!isset($quantity)) {
throw new GraphQlInputException(__('Missing key "quantity" in cart item data'));
if (!isset($cartItemData['data']['quantity'])) {
throw new GraphQlInputException(__('Missed "qty" in cart item data'));
}
return (float)$quantity;
$quantity = (float)$cartItemData['data']['quantity'];

if ($quantity <= 0) {
throw new GraphQlInputException(
__('Please enter a number greater than 0 in this field.')
);
}
return $quantity;
}

/**
Expand All @@ -136,13 +125,17 @@ private function extractQuantity(array $cartItemData): float
*/
private function extractCustomizableOptions(array $cartItemData): array
{
$customizableOptions = $this->arrayManager->get('customizable_options', $cartItemData, []);
if (!isset($cartItemData['customizable_options']) || empty($cartItemData['customizable_options'])) {
return [];
}

$customizableOptionsData = [];
foreach ($customizableOptions as $customizableOption) {
$customizableOptionsData[$customizableOption['id']] = $this->convertCustomOptions(
$customizableOption['value']
);
foreach ($cartItemData['customizable_options'] as $customizableOption) {
if (isset($customizableOption['value_string'])) {
$customizableOptionsData[$customizableOption['id']] = $this->convertCustomOptions(
$customizableOption['value_string']
);
}
}
return $customizableOptionsData;
}
Expand Down Expand Up @@ -170,6 +163,7 @@ private function createBuyRequest(float $quantity, array $customOptions): DataOb
*/
private function convertCustomOptions(string $value)
{
$value = trim($value);
if (substr($value, 0, 1) === "[" &&
substr($value, strlen($value) - 1, 1) === "]") {
return explode(',', substr($value, 1, -1));
Expand Down
7 changes: 3 additions & 4 deletions app/code/Magento/QuoteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ input CartItemInput {

input CustomizableOptionInput {
id: Int!
value: String!
value_string: String!
}

input ApplyCouponToCartInput {
Expand Down Expand Up @@ -314,16 +314,15 @@ interface CartItemInterface @typeResolver(class: "Magento\\QuoteGraphQl\\Model\\
type SelectedCustomizableOption {
id: Int!
label: String!
type: String!
is_required: Int!
is_required: Boolean!
values: [SelectedCustomizableOptionValue!]!
sort_order: Int!
}

type SelectedCustomizableOptionValue {
id: Int!
label: String!
value: String!
value: String
price: CartItemSelectedOptionValuePrice!
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,41 +50,11 @@ public function testAddSimpleProductWithOptions()
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1');

$customOptionsValues = $this->getCustomOptionsValuesForQuery($sku);

/* Generate customizable options fragment for GraphQl request */
$queryCustomizableOptions = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues));
$queryCustomizableOptionValues = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues));

$query = <<<QUERY
mutation {
addSimpleProductsToCart(
input: {
cart_id: "{$maskedQuoteId}",
cartItems: [
{
data: {
quantity: $quantity
sku: "$sku"
},
customizable_options: $queryCustomizableOptions
}
]
}
) {
cart {
items {
... on SimpleCartItem {
customizable_options {
label
values {
value
}
}
}
}
}
}
}
QUERY;
$customizableOptions = "customizable_options: {$queryCustomizableOptionValues}";
$query = $this->getQuery($maskedQuoteId, $sku, $quantity, $customizableOptions);

$response = $this->graphQlMutation($query);

Expand All @@ -95,7 +65,7 @@ public function testAddSimpleProductWithOptions()
$assignedOptionsCount = count($customOptionsValues);
for ($counter = 0; $counter < $assignedOptionsCount; $counter++) {
self::assertEquals(
$customOptionsValues[$counter]['value'],
$customOptionsValues[$counter]['value_string'],
$customizableOptionsOutput[$counter]['values'][0]['value']
);
}
Expand All @@ -107,13 +77,31 @@ public function testAddSimpleProductWithOptions()
* @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_options.php
* @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
*/
public function testAddSimpleProductWithNoRequiredOptionsSet()
public function testAddSimpleProductWithMissedRequiredOptionsSet()
{
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1');
$sku = 'simple';
$quantity = 1;
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1');
$customizableOptions = '';

$query = <<<QUERY
$query = $this->getQuery($maskedQuoteId, $sku, $quantity, $customizableOptions);

self::expectExceptionMessage(
'The product\'s required option(s) weren\'t entered. Make sure the options are entered and try again.'
);
$this->graphQlMutation($query);
}

/**
* @param string $maskedQuoteId
* @param string $sku
* @param float $quantity
* @param string $customizableOptions
* @return string
*/
private function getQuery(string $maskedQuoteId, string $sku, float $quantity, string $customizableOptions): string
{
return <<<QUERY
mutation {
addSimpleProductsToCart(
input: {
Expand All @@ -124,6 +112,7 @@ public function testAddSimpleProductWithNoRequiredOptionsSet()
quantity: $quantity
sku: "$sku"
}
{$customizableOptions}
}
]
}
Expand All @@ -134,7 +123,7 @@ public function testAddSimpleProductWithNoRequiredOptionsSet()
customizable_options {
label
values {
value
value
}
}
}
Expand All @@ -143,12 +132,6 @@ public function testAddSimpleProductWithNoRequiredOptionsSet()
}
}
QUERY;

self::expectExceptionMessage(
'The product\'s required option(s) weren\'t entered. Make sure the options are entered and try again.'
);

$this->graphQlMutation($query);
}

/**
Expand All @@ -168,13 +151,13 @@ private function getCustomOptionsValuesForQuery(string $sku): array
if ($optionType == 'field' || $optionType == 'area') {
$customOptionsValues[] = [
'id' => (int) $customOption->getOptionId(),
'value' => 'test'
'value_string' => 'test'
];
} elseif ($optionType == 'drop_down') {
$optionSelectValues = $customOption->getValues();
$customOptionsValues[] = [
'id' => (int) $customOption->getOptionId(),
'value' => reset($optionSelectValues)->getOptionTypeId()
'value_string' => reset($optionSelectValues)->getOptionTypeId()
];
}
}
Expand Down
Loading

0 comments on commit 1315577

Please sign in to comment.