diff --git a/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php b/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php index e1106a3f696e4..cd582ffda9244 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php +++ b/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php @@ -10,9 +10,12 @@ use Magento\Catalog\Model\Product\Option\Type\Date as ProductDateOptionType; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Stdlib\DateTime; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; /** - * @inheritdoc + * CatalogGraphQl product option date type + * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class DateType extends ProductDateOptionType { @@ -43,6 +46,13 @@ private function formatValues($values) if (isset($values[$this->getOption()->getId()])) { $value = $values[$this->getOption()->getId()]; $dateTime = \DateTime::createFromFormat(DateTime::DATETIME_PHP_FORMAT, $value); + + if ($dateTime === false) { + throw new GraphQlInputException( + __('Invalid format provided. Please use \'Y-m-d H:i:s\' format.') + ); + } + $values[$this->getOption()->getId()] = [ 'date' => $value, 'year' => $dateTime->format('Y'), diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddDownloadableProductWithCustomOptionsToCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddDownloadableProductWithCustomOptionsToCartTest.php index fa7d1194c7f83..8b8973ad0fd95 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddDownloadableProductWithCustomOptionsToCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddDownloadableProductWithCustomOptionsToCartTest.php @@ -58,7 +58,11 @@ public function testAddDownloadableProductWithOptions() $customOptionsValues = $this->getCustomOptionsValuesForQueryBySku->execute($sku); /* Generate customizable options fragment for GraphQl request */ - $queryCustomizableOptionValues = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues)); + $queryCustomizableOptionValues = preg_replace( + '/"([^"]+)"\s*:\s*/', + '$1:', + json_encode(array_values($customOptionsValues)) + ); $customizableOptions = "customizable_options: {$queryCustomizableOptionValues}"; $query = $this->getQuery($maskedQuoteId, $qty, $sku, $customizableOptions, $linkId); @@ -68,13 +72,14 @@ public function testAddDownloadableProductWithOptions() self::assertCount($qty, $response['addDownloadableProductsToCart']['cart']); $customizableOptionsOutput = $response['addDownloadableProductsToCart']['cart']['items'][0]['customizable_options']; - $assignedOptionsCount = count($customOptionsValues); - for ($counter = 0; $counter < $assignedOptionsCount; $counter++) { - $expectedValues = $this->buildExpectedValuesArray($customOptionsValues[$counter]['value_string']); + $count = 0; + foreach ($customOptionsValues as $value) { + $expectedValues = $this->buildExpectedValuesArray($value['value_string']); self::assertEquals( $expectedValues, - $customizableOptionsOutput[$counter]['values'] + $customizableOptionsOutput[$count]['values'] ); + $count++; } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php index b0b116b0cddad..5c2bc10bf771e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php @@ -57,7 +57,11 @@ public function testAddSimpleProductWithOptions() $customOptionsValues = $this->getCustomOptionsValuesForQueryBySku->execute($sku); /* Generate customizable options fragment for GraphQl request */ - $queryCustomizableOptionValues = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues)); + $queryCustomizableOptionValues = preg_replace( + '/"([^"]+)"\s*:\s*/', + '$1:', + json_encode(array_values($customOptionsValues)) + ); $customizableOptions = "customizable_options: {$queryCustomizableOptionValues}"; $query = $this->getQuery($maskedQuoteId, $sku, $quantity, $customizableOptions); @@ -68,13 +72,14 @@ public function testAddSimpleProductWithOptions() self::assertCount(1, $response['addSimpleProductsToCart']['cart']); $customizableOptionsOutput = $response['addSimpleProductsToCart']['cart']['items'][0]['customizable_options']; - $assignedOptionsCount = count($customOptionsValues); - for ($counter = 0; $counter < $assignedOptionsCount; $counter++) { - $expectedValues = $this->buildExpectedValuesArray($customOptionsValues[$counter]['value_string']); + $count = 0; + foreach ($customOptionsValues as $type => $value) { + $expectedValues = $this->buildExpectedValuesArray($value['value_string'], $type); self::assertEquals( $expectedValues, - $customizableOptionsOutput[$counter]['values'] + $customizableOptionsOutput[$count]['values'] ); + $count++; } } @@ -99,6 +104,33 @@ public function testAddSimpleProductWithMissedRequiredOptionsSet() $this->graphQlMutation($query); } + /** + * Test adding a simple product with wrong format value for date option + * + * @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_options.php + * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php + */ + public function testAddSimpleProductWithWrongDateOptionFormat() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1'); + $sku = 'simple'; + $quantity = 1; + + $customOptionsValues = $this->getCustomOptionsValuesForQueryBySku->execute($sku); + $customOptionsValues['date']['value_string'] = '12-12-12'; + $queryCustomizableOptionValues = preg_replace( + '/"([^"]+)"\s*:\s*/', + '$1:', + json_encode(array_values($customOptionsValues)) + ); + $customizableOptions = "customizable_options: {$queryCustomizableOptionValues}"; + $query = $this->getQuery($maskedQuoteId, $sku, $quantity, $customizableOptions); + + $this->expectExceptionMessage('Invalid format provided. Please use \'Y-m-d H:i:s\' format.'); + + $this->graphQlMutation($query); + } + /** * @param string $maskedQuoteId * @param string $sku @@ -145,10 +177,14 @@ private function getQuery(string $maskedQuoteId, string $sku, float $quantity, s * Build the part of expected response. * * @param string $assignedValue + * @param string $type option type * @return array */ - private function buildExpectedValuesArray(string $assignedValue) : array + private function buildExpectedValuesArray(string $assignedValue, string $type) : array { + if ($type === 'date') { + return [['value' => date('M d, Y', strtotime($assignedValue))]]; + } $assignedOptionsArray = explode(',', trim($assignedValue, '[]')); $expectedArray = []; foreach ($assignedOptionsArray as $assignedOption) { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddVirtualProductWithCustomOptionsToCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddVirtualProductWithCustomOptionsToCartTest.php index a8088b0b46b87..561318889e325 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddVirtualProductWithCustomOptionsToCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddVirtualProductWithCustomOptionsToCartTest.php @@ -57,7 +57,11 @@ public function testAddVirtualProductWithOptions() $customOptionsValues = $this->getCustomOptionsValuesForQueryBySku->execute($sku); /* Generate customizable options fragment for GraphQl request */ - $queryCustomizableOptionValues = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues)); + $queryCustomizableOptionValues = preg_replace( + '/"([^"]+)"\s*:\s*/', + '$1:', + json_encode(array_values($customOptionsValues)) + ); $customizableOptions = "customizable_options: {$queryCustomizableOptionValues}"; $query = $this->getQuery($maskedQuoteId, $sku, $quantity, $customizableOptions); @@ -68,13 +72,14 @@ public function testAddVirtualProductWithOptions() self::assertCount(1, $response['addVirtualProductsToCart']['cart']); $customizableOptionsOutput = $response['addVirtualProductsToCart']['cart']['items'][0]['customizable_options']; - $assignedOptionsCount = count($customOptionsValues); - for ($counter = 0; $counter < $assignedOptionsCount; $counter++) { - $expectedValues = $this->buildExpectedValuesArray($customOptionsValues[$counter]['value_string']); + $count = 0; + foreach ($customOptionsValues as $value) { + $expectedValues = $this->buildExpectedValuesArray($value['value_string']); self::assertEquals( $expectedValues, - $customizableOptionsOutput[$counter]['values'] + $customizableOptionsOutput[$count]['values'] ); + $count++; } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCustomOptionsValuesForQueryBySku.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCustomOptionsValuesForQueryBySku.php index 7514eb1c4e1d0..62cacd3e07c16 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCustomOptionsValuesForQueryBySku.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCustomOptionsValuesForQueryBySku.php @@ -40,25 +40,26 @@ public function execute(string $sku): array foreach ($customOptions as $customOption) { $optionType = $customOption->getType(); - if ($optionType == 'field' || $optionType == 'area') { - $customOptionsValues[] = [ - 'id' => (int)$customOption->getOptionId(), - 'value_string' => 'test' - ]; - } elseif ($optionType == 'drop_down') { - $optionSelectValues = $customOption->getValues(); - $customOptionsValues[] = [ - 'id' => (int)$customOption->getOptionId(), - 'value_string' => reset($optionSelectValues)->getOptionTypeId() - ]; - } elseif ($optionType == 'multiple') { - $customOptionsValues[] = [ - 'id' => (int)$customOption->getOptionId(), - 'value_string' => '[' . implode(',', array_keys($customOption->getValues())) . ']' - ]; + $customOptionsValues[$optionType]['id'] = (int)$customOption->getOptionId(); + switch ($optionType) { + case 'date': + $customOptionsValues[$optionType]['value_string'] = '2012-12-12 00:00:00'; + break; + case 'field': + case 'area': + $customOptionsValues[$optionType]['value_string'] = 'test'; + break; + case 'drop_down': + $optionSelectValues = $customOption->getValues(); + $customOptionsValues[$optionType]['value_string'] = + reset($optionSelectValues)->getOptionTypeId(); + break; + case 'multiple': + $customOptionsValues[$optionType]['value_string'] = + '[' . implode(',', array_keys($customOption->getValues())) . ']'; + break; } } - return $customOptionsValues; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_options.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_options.php index 93c7ba61c6f49..67288bec86ad5 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_options.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_options.php @@ -106,6 +106,15 @@ 'sort_order' => 2, ], ], + ], + [ + 'title' => 'date option', + 'type' => 'date', + 'price' => 80.0, + 'price_type' => 'fixed', + 'sku' => 'date option sku', + 'is_require' => false, + 'sort_order' => 6 ] ];