Skip to content

Commit 7a8b143

Browse files
committed
PWA-2137: [GraphQL] Need to bypass webonyx type validation
- tests
1 parent 8a39970 commit 7a8b143

File tree

3 files changed

+347
-0
lines changed

3 files changed

+347
-0
lines changed
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GraphQl;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
use Magento\TestFramework\TestCase\GraphQlAbstract;
14+
15+
class GraphQlTypeValidationTest extends GraphQlAbstract
16+
{
17+
/**
18+
* @var ProductRepositoryInterface
19+
*/
20+
private $productRepository;
21+
22+
/**
23+
* @var GetMaskedQuoteIdByReservedOrderId
24+
*/
25+
private $getMaskedQuoteIdByReservedOrderId;
26+
27+
protected function setUp(): void
28+
{
29+
$objectManager = Bootstrap::getObjectManager();
30+
$this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
31+
$this->productRepository = $objectManager->get(ProductRepositoryInterface::class);
32+
}
33+
34+
/**
35+
*
36+
* Tests that field expecting an Int type ; but Float is provided
37+
*
38+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
39+
*/
40+
public function testIntegerExpectedWhenFloatProvided()
41+
{
42+
$query
43+
= <<<'QUERY'
44+
query GetProductsQuery($pageSize: Int, $filterInput: ProductAttributeFilterInput, $currentPage:Int ) {
45+
products(
46+
filter: $filterInput
47+
pageSize: $pageSize
48+
currentPage: $currentPage
49+
50+
) {
51+
items {
52+
sku
53+
name
54+
id
55+
}
56+
}
57+
}
58+
QUERY;
59+
60+
$variables = [
61+
62+
'filterInput' => [
63+
'sku' => [
64+
'eq' => 'simple_product',
65+
],
66+
],
67+
'pageSize' => 1,
68+
'currentPage' => 1.1
69+
];
70+
$this->expectException(\Exception::class);
71+
$this->expectExceptionMessage('Variable "$currentPage" got invalid value 1.1; Expected type Int; Int cannot represent non-integer value: 1.1');
72+
$this->graphQlQuery($query, $variables);
73+
}
74+
75+
/**
76+
* Tests that field expects an Float type ; but String is provided
77+
*
78+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
79+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
80+
*/
81+
public function testFloatExpectedWhenStringProvided()
82+
{
83+
$sku = 'simple_product';
84+
/** @var \Magento\Catalog\Model\Product $product */
85+
$product = $this->productRepository->get($sku, false, null, true);
86+
$cartId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
87+
$query = $this->addProductsToCart();
88+
$variables = [
89+
'cartId' => $cartId,
90+
'sku' => $sku,
91+
'quantity' => '1.9'
92+
];
93+
$response = $this->graphQlMutation($query, $variables);
94+
$this->assertArrayNotHasKey('errors', $response);
95+
$this->assertArrayHasKey('addProductsToCart', $response);
96+
$this->assertCount(1, $response['addProductsToCart']['cart']['items']);
97+
$this->assertEquals($product->getSku(), $response['addProductsToCart']['cart']['items'][0]['product']['sku']);
98+
$this->assertEquals(1.9, $response['addProductsToCart']['cart']['items'][0]['quantity']);
99+
}
100+
101+
/**
102+
* Verify that query is resolved even when field expecting an Int is provided with String type data
103+
*
104+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
105+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
106+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
107+
*/
108+
public function testIntegerExpectedWhenStringProvided()
109+
{
110+
$cartId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
111+
$quantity = 5;
112+
$itemId = $this->getCartItemId($cartId);
113+
$query
114+
= <<<'MUTATION'
115+
mutation updateItemQuantity($cartId: String!, $itemId: Int!, $quantity: Float!)
116+
{
117+
updateCartItems(input:
118+
{cart_id: $cartId,
119+
cart_items:
120+
[
121+
{cart_item_id: $itemId,
122+
quantity: $quantity}]}
123+
)
124+
{
125+
cart
126+
{
127+
id
128+
items {id product {sku id } quantity}
129+
}
130+
}
131+
}
132+
MUTATION;
133+
134+
// $itemId expects an integer type, but a string value is provided
135+
$variables = [
136+
'cartId' => $cartId,
137+
'itemId'=> "{$itemId}",
138+
'quantity'=> $quantity
139+
];
140+
$response = $this->graphQlMutation($query, $variables);
141+
$this->assertArrayNotHasKey('errors', $response);
142+
$this->assertArrayHasKey('updateCartItems', $response);
143+
$this->assertCount(1, $response['updateCartItems']['cart']['items']);
144+
$this->assertEquals('simple_product', $response['updateCartItems']['cart']['items'][0]['product']['sku']);
145+
$this->assertEquals(5, $response['updateCartItems']['cart']['items'][0]['quantity']);
146+
$this->assertEquals($itemId, $response['updateCartItems']['cart']['items'][0]['id']);
147+
}
148+
149+
/**
150+
* Verify that query doesn't return error when an integer is passed for a field where string is expected
151+
*
152+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product_with_numeric_sku.php
153+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
154+
*/
155+
public function testStringExpectedWhenFloatProvided()
156+
{
157+
$cartId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
158+
$query = $this->addProductsToCart();
159+
160+
// sku is expecting a string ; but an float s given.
161+
// And quantity is expecting a float, but value is passed as string
162+
$variables = [
163+
'cartId' => $cartId,
164+
'sku' => 123.78,
165+
'quantity' => '5.60'
166+
];
167+
$response = $this->graphQlMutation($query, $variables);
168+
$this->assertArrayNotHasKey('errors', $response);
169+
$this->assertArrayHasKey('addProductsToCart', $response);
170+
$this->assertCount(1, $response['addProductsToCart']['cart']['items']);
171+
$this->assertEquals('123.78', $response['addProductsToCart']['cart']['items'][0]['product']['sku']);
172+
$this->assertEquals(5.60, $response['addProductsToCart']['cart']['items'][0]['quantity']);
173+
}
174+
175+
/**
176+
* Verify that query doesn't return error when an integer is passed for a field where string is expected
177+
*
178+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product_with_numeric_sku.php
179+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
180+
*/
181+
public function testStringExpectedWhenArrayProvided()
182+
{
183+
$cartId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
184+
$query = $this->addProductsToCart();
185+
186+
// sku is expecting a string ; but an array is passed.
187+
// And quantity is expecting a float, but value is passed as string
188+
$variables = [
189+
'cartId' => $cartId,
190+
'sku' => ['123.78'],
191+
'quantity' => '5.60'
192+
];
193+
$this->expectException(\Exception::class);
194+
$this->expectExceptionMessage('Variable "$sku" got invalid value ["123.78"]; Expected type String; String cannot represent a non string value: ["123.78"]');
195+
$this->graphQlMutation($query, $variables);
196+
}
197+
198+
/**
199+
* Verify that query doesn't return error when an integer is passed for a field where string is expected
200+
*
201+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product_with_numeric_sku.php
202+
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
203+
*/
204+
public function testFloatExpectedWhenNonNumericStringProvided()
205+
{
206+
$cartId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
207+
$query = $this->addProductsToCart();
208+
209+
// quantity is expecting a float, but a non-numeric string is passed
210+
$variables = [
211+
'cartId' => $cartId,
212+
'sku' => '123.78',
213+
'quantity' => 'ten'
214+
];
215+
$this->expectException(\Exception::class);
216+
$this->expectExceptionMessage('Variable "$quantity" got invalid value "ten"; Expected type Float; Float cannot represent non numeric value: ten');
217+
$this->graphQlMutation($query, $variables);
218+
}
219+
220+
/**
221+
* Query the cart to get the cart item id
222+
*
223+
* @param string $cartId
224+
* @return string
225+
* @throws \Exception
226+
*/
227+
private function getCartItemId(string $cartId): string
228+
{
229+
$cartQuery = <<<QUERY
230+
{
231+
cart(cart_id: "$cartId") {
232+
id
233+
items {
234+
id
235+
}
236+
}
237+
}
238+
QUERY;
239+
$result = $this->graphQlQuery($cartQuery);
240+
$this->assertArrayNotHasKey('errors', $result);
241+
$this->assertCount(1, $result['cart']['items']);
242+
return $result['cart']['items'][0]['id'];
243+
}
244+
245+
/**
246+
* @return string
247+
*/
248+
private function addProductsToCart():string
249+
{
250+
return <<<'MUTATION'
251+
mutation AddItemsToCart($cartId: String!, $sku: String!, $quantity: Float!)
252+
{
253+
addProductsToCart (
254+
cartId:$cartId
255+
cartItems:[
256+
{
257+
sku:$sku
258+
quantity:$quantity
259+
}]
260+
)
261+
{
262+
cart {
263+
id
264+
total_quantity
265+
items { product {sku id } quantity}
266+
}
267+
}
268+
}
269+
MUTATION;
270+
}
271+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\Catalog\Api\Data\ProductInterfaceFactory;
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
12+
use Magento\Catalog\Model\Product\Type;
13+
use Magento\Catalog\Model\Product\Visibility;
14+
use Magento\Framework\Api\DataObjectHelper;
15+
use Magento\TestFramework\Helper\Bootstrap;
16+
17+
$objectManager = Bootstrap::getObjectManager();
18+
/** @var ProductInterfaceFactory $productFactory */
19+
$productFactory = $objectManager->get(ProductInterfaceFactory::class);
20+
/** @var DataObjectHelper $dataObjectHelper */
21+
$dataObjectHelper = Bootstrap::getObjectManager()->get(DataObjectHelper::class);
22+
/** @var ProductRepositoryInterface $productRepository */
23+
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
24+
25+
$product = $productFactory->create();
26+
$productData = [
27+
ProductInterface::TYPE_ID => Type::TYPE_SIMPLE,
28+
ProductInterface::ATTRIBUTE_SET_ID => 4,
29+
ProductInterface::SKU => '123.78',
30+
ProductInterface::NAME => 'Simple 123',
31+
ProductInterface::PRICE => 10,
32+
ProductInterface::VISIBILITY => Visibility::VISIBILITY_BOTH,
33+
ProductInterface::STATUS => Status::STATUS_ENABLED,
34+
];
35+
$dataObjectHelper->populateWithArray($product, $productData, ProductInterface::class);
36+
/** Out of interface */
37+
$product
38+
->setWebsiteIds([1])
39+
->setStockData([
40+
'qty' => 85.5,
41+
'is_in_stock' => true,
42+
'manage_stock' => true,
43+
'is_qty_decimal' => true
44+
]);
45+
$productRepository->save($product);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\Catalog\Api\ProductRepositoryInterface;
9+
use Magento\Framework\Registry;
10+
use Magento\TestFramework\Helper\Bootstrap;
11+
12+
$objectManager = Bootstrap::getObjectManager();
13+
/** @var ProductRepositoryInterface $productRepository */
14+
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
15+
/** @var Registry $registry */
16+
$registry = $objectManager->get(Registry::class);
17+
18+
$currentArea = $registry->registry('isSecureArea');
19+
$registry->unregister('isSecureArea');
20+
$registry->register('isSecureArea', true);
21+
22+
try {
23+
$productRepository->deleteById('123.78');
24+
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
25+
/**
26+
* Tests which are wrapped with MySQL transaction clear all data by transaction rollback.
27+
*/
28+
}
29+
30+
$registry->unregister('isSecureArea');
31+
$registry->register('isSecureArea', $currentArea);

0 commit comments

Comments
 (0)