CustomerCartTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. <?php
  2. namespace Webkul\BagistoApi\Tests\Feature\GraphQL;
  3. use Webkul\BagistoApi\Tests\GraphQLTestCase;
  4. class CustomerCartTest extends GraphQLTestCase
  5. {
  6. private function loginCustomerAndGetToken(): string
  7. {
  8. // Use our test customer helper to create a customer with proper token
  9. $customerData = $this->createTestCustomer();
  10. return $customerData['token'];
  11. }
  12. private function customerHeaders(string $token): array
  13. {
  14. return [
  15. 'Authorization' => 'Bearer '.$token,
  16. ];
  17. }
  18. private function createCustomerCartWithItem(string $token, int $quantity = 2): array
  19. {
  20. // Use our test product helper to get a product with inventory
  21. $productData = $this->createTestProduct();
  22. $product = $productData['product'];
  23. $mutation = <<<'GQL'
  24. mutation createAddProductInCart($productId: Int!, $quantity: Int!) {
  25. createAddProductInCart(input: {productId: $productId, quantity: $quantity}) {
  26. addProductInCart {
  27. id
  28. itemsCount
  29. items {
  30. edges {
  31. node {
  32. id
  33. productId
  34. quantity
  35. }
  36. }
  37. }
  38. }
  39. }
  40. }
  41. GQL;
  42. $response = $this->graphQL($mutation, [
  43. 'productId' => $product->id,
  44. 'quantity' => $quantity,
  45. ], $this->customerHeaders($token));
  46. $response->assertSuccessful();
  47. $cart = $response->json('data.createAddProductInCart.addProductInCart');
  48. $cartItemId = $response->json('data.createAddProductInCart.addProductInCart.items.edges.0.node.id');
  49. $this->assertNotNull($cart);
  50. $this->assertNotNull($cartItemId);
  51. return [
  52. 'product' => $product->id,
  53. 'cartId' => (int) ($cart['_id'] ?? $cart['id'] ?? 0),
  54. 'cartItemId' => (int) $cartItemId,
  55. ];
  56. }
  57. /**
  58. * Create Simple Cart (Customer)
  59. */
  60. public function test_create_simple_cart_as_customer(): void
  61. {
  62. $token = $this->loginCustomerAndGetToken();
  63. $mutation = <<<'GQL'
  64. mutation createCart {
  65. createCartToken(input: {}) {
  66. cartToken {
  67. id
  68. _id
  69. cartToken
  70. customerId
  71. channelId
  72. itemsCount
  73. subtotal
  74. baseSubtotal
  75. discountAmount
  76. baseDiscountAmount
  77. taxAmount
  78. baseTaxAmount
  79. shippingAmount
  80. baseShippingAmount
  81. grandTotal
  82. baseGrandTotal
  83. formattedSubtotal
  84. formattedDiscountAmount
  85. formattedTaxAmount
  86. formattedShippingAmount
  87. formattedGrandTotal
  88. couponCode
  89. success
  90. message
  91. sessionToken
  92. isGuest
  93. }
  94. }
  95. }
  96. GQL;
  97. $response = $this->graphQL($mutation, [], $this->customerHeaders($token));
  98. $response->assertSuccessful();
  99. $data = $response->json('data.createCartToken.cartToken');
  100. $this->assertNotNull($data);
  101. $this->assertTrue((bool) ($data['success'] ?? false));
  102. $this->assertFalse((bool) ($data['isGuest'] ?? true));
  103. $this->assertNotNull($data['customerId'] ?? null);
  104. }
  105. /**
  106. * Add Product In Cart (Customer) -- Failed
  107. */
  108. public function test_create_add_product_in_cart_as_customer(): void
  109. {
  110. // Use our helper method to create a fake customer
  111. $customerData = $this->createTestCustomer();
  112. $customer = $customerData['customer'];
  113. $token = $customerData['token'];
  114. // Use our helper method to create a complete test product
  115. $productData = $this->createTestProduct();
  116. $product = $productData['product'];
  117. $mutation = <<<'GQL'
  118. mutation createAddProductInCart($productId: Int!, $quantity: Int!) {
  119. createAddProductInCart(input: {productId: $productId, quantity: $quantity}) {
  120. addProductInCart {
  121. id
  122. _id
  123. cartToken
  124. customerId
  125. channelId
  126. subtotal
  127. baseSubtotal
  128. discountAmount
  129. baseDiscountAmount
  130. taxAmount
  131. baseTaxAmount
  132. shippingAmount
  133. baseShippingAmount
  134. grandTotal
  135. baseGrandTotal
  136. formattedSubtotal
  137. formattedDiscountAmount
  138. formattedTaxAmount
  139. formattedShippingAmount
  140. formattedGrandTotal
  141. couponCode
  142. items {
  143. totalCount
  144. pageInfo {
  145. startCursor
  146. endCursor
  147. hasNextPage
  148. hasPreviousPage
  149. }
  150. edges {
  151. cursor
  152. node {
  153. id
  154. cartId
  155. productId
  156. name
  157. sku
  158. quantity
  159. price
  160. basePrice
  161. total
  162. baseTotal
  163. discountAmount
  164. baseDiscountAmount
  165. taxAmount
  166. baseTaxAmount
  167. type
  168. formattedPrice
  169. formattedTotal
  170. priceInclTax
  171. basePriceInclTax
  172. formattedPriceInclTax
  173. totalInclTax
  174. baseTotalInclTax
  175. formattedTotalInclTax
  176. productUrlKey
  177. canChangeQty
  178. }
  179. }
  180. }
  181. success
  182. message
  183. sessionToken
  184. isGuest
  185. itemsQty
  186. itemsCount
  187. haveStockableItems
  188. paymentMethod
  189. paymentMethodTitle
  190. subTotalInclTax
  191. baseSubTotalInclTax
  192. formattedSubTotalInclTax
  193. taxTotal
  194. formattedTaxTotal
  195. shippingAmountInclTax
  196. baseShippingAmountInclTax
  197. formattedShippingAmountInclTax
  198. }
  199. }
  200. }
  201. GQL;
  202. $response = $this->graphQL($mutation, [
  203. 'productId' => $product->id,
  204. 'quantity' => 1,
  205. ], $this->customerHeaders($token));
  206. $response->assertSuccessful();
  207. $data = $response->json('data.createAddProductInCart.addProductInCart');
  208. $this->assertNotNull($data);
  209. $this->assertNotNull($data['customerId'] ?? null);
  210. $this->assertGreaterThan(0, (int) ($data['itemsCount'] ?? 0));
  211. $this->assertSame($product->id, $data['items']['edges'][0]['node']['productId'] ?? null);
  212. $this->assertSame(1, $data['items']['edges'][0]['node']['quantity'] ?? null);
  213. }
  214. /**
  215. * Update Cart Item Quantity (Customer) -- Failed
  216. */
  217. public function test_update_cart_item_quantity_as_customer(): void
  218. {
  219. $token = $this->loginCustomerAndGetToken();
  220. $headers = $this->customerHeaders($token);
  221. // Use our test product helper to get a product with inventory
  222. $productData = $this->createTestProduct();
  223. $product = $productData['product'];
  224. $addMutation = <<<'GQL'
  225. mutation createAddProductInCart($productId: Int!, $quantity: Int!) {
  226. createAddProductInCart(input: {productId: $productId, quantity: $quantity}) {
  227. addProductInCart {
  228. items {
  229. edges {
  230. node {
  231. id
  232. productId
  233. quantity
  234. }
  235. }
  236. }
  237. }
  238. }
  239. }
  240. GQL;
  241. $addResponse = $this->graphQL($addMutation, [
  242. 'productId' => $product->id,
  243. 'quantity' => 9,
  244. ], $headers);
  245. $addResponse->assertSuccessful();
  246. $cartItemId = $addResponse->json('data.createAddProductInCart.addProductInCart.items.edges.0.node.id');
  247. $this->assertNotNull($cartItemId, 'cart item id is missing for update test');
  248. $updateMutation = <<<'GQL'
  249. mutation createUpdateCartItem($cartItemId: Int!, $quantity: Int!) {
  250. createUpdateCartItem(input: {cartItemId: $cartItemId, quantity: $quantity}) {
  251. updateCartItem {
  252. id
  253. customerId
  254. itemsCount
  255. items {
  256. edges {
  257. node {
  258. id
  259. productId
  260. quantity
  261. }
  262. }
  263. }
  264. }
  265. }
  266. }
  267. GQL;
  268. $updateResponse = $this->graphQL($updateMutation, [
  269. 'cartItemId' => (int) $cartItemId,
  270. 'quantity' => 1,
  271. ], $headers);
  272. $updateResponse->assertSuccessful();
  273. $data = $updateResponse->json('data.createUpdateCartItem.updateCartItem');
  274. $this->assertNotNull($data);
  275. $this->assertNotNull($data['customerId'] ?? null);
  276. $this->assertGreaterThan(0, (int) ($data['itemsCount'] ?? 0));
  277. $this->assertSame($product->id, $data['items']['edges'][0]['node']['productId'] ?? null);
  278. $this->assertSame(1, $data['items']['edges'][0]['node']['quantity'] ?? null);
  279. }
  280. /**
  281. * Get Cart Details (Customer)
  282. */
  283. public function test_read_cart_as_customer(): void
  284. {
  285. $token = $this->loginCustomerAndGetToken();
  286. $this->createCustomerCartWithItem($token, 3);
  287. $mutation = <<<'GQL'
  288. mutation createReadCart {
  289. createReadCart(input: {}) {
  290. readCart {
  291. id
  292. _id
  293. customerId
  294. itemsCount
  295. itemsQty
  296. items {
  297. totalCount
  298. edges {
  299. node {
  300. id
  301. productId
  302. quantity
  303. }
  304. }
  305. }
  306. }
  307. }
  308. }
  309. GQL;
  310. $response = $this->graphQL($mutation, [], $this->customerHeaders($token));
  311. $response->assertSuccessful();
  312. $data = $response->json('data.createReadCart.readCart');
  313. $this->assertNotNull($data);
  314. $this->assertNotNull($data['customerId'] ?? null);
  315. $this->assertGreaterThan(0, (int) ($data['itemsCount'] ?? 0));
  316. $this->assertGreaterThan(0, (int) ($data['items']['totalCount'] ?? 0));
  317. }
  318. /**
  319. * Remove Cart Item (Customer) -- Failed
  320. */
  321. public function test_remove_cart_item_as_customer(): void
  322. {
  323. $token = $this->loginCustomerAndGetToken();
  324. $cart = $this->createCustomerCartWithItem($token, 2);
  325. $mutation = <<<'GQL'
  326. mutation createRemoveCartItem($cartItemId: Int!) {
  327. createRemoveCartItem(input: {cartItemId: $cartItemId}) {
  328. removeCartItem {
  329. id
  330. itemsCount
  331. subtotal
  332. grandTotal
  333. discountAmount
  334. }
  335. }
  336. }
  337. GQL;
  338. $response = $this->graphQL($mutation, [
  339. 'cartItemId' => $cart['cartItemId'],
  340. ], $this->customerHeaders($token));
  341. $response->assertSuccessful();
  342. $data = $response->json('data.createRemoveCartItem.removeCartItem');
  343. $this->assertNotNull($data);
  344. $this->assertLessThanOrEqual(0, (int) ($data['itemsCount'] ?? 0));
  345. }
  346. /**
  347. * Apply Coupon (Customer)
  348. */
  349. public function test_apply_coupon_as_customer(): void
  350. {
  351. $token = $this->loginCustomerAndGetToken();
  352. $this->createCustomerCartWithItem($token, 1);
  353. $mutation = <<<'GQL'
  354. mutation createApplyCoupon($couponCode: String!) {
  355. createApplyCoupon(input: {couponCode: $couponCode}) {
  356. applyCoupon {
  357. id
  358. couponCode
  359. discountAmount
  360. formattedDiscountAmount
  361. }
  362. }
  363. }
  364. GQL;
  365. $response = $this->graphQL($mutation, [
  366. 'couponCode' => 'DISCOUNT10',
  367. ], $this->customerHeaders($token));
  368. $response->assertSuccessful();
  369. $json = $response->json();
  370. if (isset($json['errors'])) {
  371. $this->assertNotEmpty($json['errors']);
  372. return;
  373. }
  374. $data = $response->json('data.createApplyCoupon.applyCoupon');
  375. $this->assertNotNull($data);
  376. $this->assertArrayHasKey('couponCode', $data);
  377. }
  378. /**
  379. * Remove Coupon (Customer)
  380. */
  381. public function test_remove_coupon_as_customer(): void
  382. {
  383. $token = $this->loginCustomerAndGetToken();
  384. $this->createCustomerCartWithItem($token, 1);
  385. $mutation = <<<'GQL'
  386. mutation createRemoveCoupon {
  387. createRemoveCoupon(input: {}) {
  388. removeCoupon {
  389. id
  390. couponCode
  391. discountAmount
  392. formattedDiscountAmount
  393. }
  394. }
  395. }
  396. GQL;
  397. $response = $this->graphQL($mutation, [], $this->customerHeaders($token));
  398. $response->assertSuccessful();
  399. $json = $response->json();
  400. if (isset($json['errors'])) {
  401. $this->assertNotEmpty($json['errors']);
  402. return;
  403. }
  404. $data = $response->json('data.createRemoveCoupon.removeCoupon');
  405. $this->assertNotNull($data);
  406. $this->assertArrayHasKey('couponCode', $data);
  407. }
  408. }