GuestCheckoutTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. <?php
  2. namespace Webkul\BagistoApi\Tests\Feature\GraphQL;
  3. use Webkul\BagistoApi\Tests\GraphQLTestCase;
  4. class GuestCheckoutTest extends GraphQLTestCase
  5. {
  6. /**
  7. * Get guest cart token from the createCart mutation response
  8. */
  9. private function getGuestCartToken(): string
  10. {
  11. $mutation = <<<'GQL'
  12. mutation createCart {
  13. createCartToken(input: {}) {
  14. cartToken {
  15. id
  16. _id
  17. cartToken
  18. customerId
  19. channelId
  20. itemsCount
  21. subtotal
  22. baseSubtotal
  23. discountAmount
  24. baseDiscountAmount
  25. taxAmount
  26. baseTaxAmount
  27. shippingAmount
  28. baseShippingAmount
  29. grandTotal
  30. baseGrandTotal
  31. formattedSubtotal
  32. formattedDiscountAmount
  33. formattedTaxAmount
  34. formattedShippingAmount
  35. formattedGrandTotal
  36. couponCode
  37. success
  38. message
  39. sessionToken
  40. isGuest
  41. }
  42. }
  43. }
  44. GQL;
  45. $response = $this->graphQL($mutation);
  46. $response->assertSuccessful();
  47. $data = $response->json('data.createCartToken.cartToken');
  48. $this->assertNotNull($data, 'cartToken response is null');
  49. $this->assertTrue((bool) ($data['success'] ?? false));
  50. // Use cartToken as the bearer token
  51. $token = $data['cartToken'] ?? null;
  52. $this->assertNotEmpty($token, 'guest cart token is missing');
  53. return $token;
  54. }
  55. /**
  56. * Helper method to get authorization headers with guest cart token
  57. */
  58. private function guestHeaders(string $token): array
  59. {
  60. return [
  61. 'Authorization' => 'Bearer ' . $token,
  62. ];
  63. }
  64. /**
  65. * Add product to cart first for checkout tests
  66. */
  67. private function addProductToCart(string $token): int
  68. {
  69. // Use test product helper to get a product with inventory
  70. $productData = $this->createTestProduct();
  71. $product = $productData['product'];
  72. $mutation = <<<'GQL'
  73. mutation createAddProductInCart($productId: Int!, $quantity: Int!) {
  74. createAddProductInCart(input: {productId: $productId, quantity: $quantity}) {
  75. addProductInCart {
  76. id
  77. itemsCount
  78. }
  79. }
  80. }
  81. GQL;
  82. $response = $this->graphQL($mutation, [
  83. 'productId' => $product->id,
  84. 'quantity' => 1,
  85. ], $this->guestHeaders($token));
  86. $response->assertSuccessful();
  87. return $product->id;
  88. }
  89. /**
  90. * Get Shipping Methods
  91. */
  92. public function test_get_shipping_methods(): void
  93. {
  94. $token = $this->getGuestCartToken();
  95. $query = <<<'GQL'
  96. query checkoutShippingRates {
  97. collectionShippingRates {
  98. _id
  99. id
  100. code
  101. description
  102. method
  103. price
  104. label
  105. }
  106. }
  107. GQL;
  108. $response = $this->graphQL($query, [], $this->guestHeaders($token));
  109. $response->assertSuccessful();
  110. $data = $response->json('data.collectionShippingRates');
  111. $this->assertNotNull($data, 'shipping rates response is null');
  112. $this->assertIsArray($data, 'shipping rates is not an array');
  113. }
  114. /**
  115. * Get Payment Methods
  116. */
  117. public function test_get_payment_methods(): void
  118. {
  119. $token = $this->getGuestCartToken();
  120. $query = <<<'GQL'
  121. query checkoutPaymentMethods {
  122. collectionPaymentMethods {
  123. id
  124. _id
  125. method
  126. title
  127. description
  128. icon
  129. isAllowed
  130. }
  131. }
  132. GQL;
  133. $response = $this->graphQL($query, [], $this->guestHeaders($token));
  134. $response->assertSuccessful();
  135. $data = $response->json('data.collectionPaymentMethods');
  136. $this->assertNotNull($data, 'payment methods response is null');
  137. $this->assertIsArray($data, 'payment methods is not an array');
  138. }
  139. /**
  140. * Set Billing/Shipping Address (Guest)
  141. */
  142. public function test_set_checkout_address(): void
  143. {
  144. $token = $this->getGuestCartToken();
  145. // First add product to cart
  146. $this->addProductToCart($token);
  147. $headers = $this->guestHeaders($token);
  148. $query = <<<'GQL'
  149. mutation createCheckoutAddress(
  150. $billingFirstName: String!
  151. $billingLastName: String!
  152. $billingEmail: String!
  153. $billingAddress: String!
  154. $billingCity: String!
  155. $billingCountry: String!
  156. $billingState: String!
  157. $billingPostcode: String!
  158. $billingPhoneNumber: String!
  159. $useForShipping: Boolean
  160. ) {
  161. createCheckoutAddress(
  162. input: {
  163. billingFirstName: $billingFirstName
  164. billingLastName: $billingLastName
  165. billingEmail: $billingEmail
  166. billingAddress: $billingAddress
  167. billingCity: $billingCity
  168. billingCountry: $billingCountry
  169. billingState: $billingState
  170. billingPostcode: $billingPostcode
  171. billingPhoneNumber: $billingPhoneNumber
  172. useForShipping: $useForShipping
  173. }
  174. ) {
  175. checkoutAddress {
  176. _id
  177. success
  178. message
  179. id
  180. cartToken
  181. billingFirstName
  182. billingLastName
  183. billingAddress
  184. billingCity
  185. billingState
  186. billingPostcode
  187. billingPhoneNumber
  188. shippingFirstName
  189. shippingLastName
  190. shippingCity
  191. }
  192. }
  193. }
  194. GQL;
  195. $variables = [
  196. 'billingFirstName' => 'John',
  197. 'billingLastName' => 'Doe',
  198. 'billingEmail' => 'john@example.com',
  199. 'billingAddress' => '123 Main St',
  200. 'billingCity' => 'Los Angeles',
  201. 'billingCountry' => 'IN',
  202. 'billingState' => 'UP',
  203. 'billingPostcode' => '201301',
  204. 'billingPhoneNumber' => '2125551234',
  205. 'useForShipping' => true,
  206. ];
  207. $response = $this->graphQL($query, $variables, $headers);
  208. $response->assertSuccessful();
  209. $data = $response->json('data.createCheckoutAddress.checkoutAddress');
  210. $this->assertNotNull($data, 'checkout address response is null');
  211. $this->assertArrayHasKey('_id', $data);
  212. $this->assertArrayHasKey('success', $data);
  213. }
  214. /**
  215. * Set Shipping Method (Guest)
  216. */
  217. public function test_set_shipping_method(): void
  218. {
  219. $token = $this->getGuestCartToken();
  220. // First add product to cart and set address
  221. $this->addProductToCart($token);
  222. // Set address first
  223. $this->setCheckoutAddress($token);
  224. $headers = $this->guestHeaders($token);
  225. $query = <<<'GQL'
  226. mutation createCheckoutShippingMethod(
  227. $shippingMethod: String!
  228. ) {
  229. createCheckoutShippingMethod(
  230. input: {
  231. shippingMethod: $shippingMethod
  232. }
  233. ) {
  234. checkoutShippingMethod {
  235. success
  236. id
  237. message
  238. }
  239. }
  240. }
  241. GQL;
  242. $variables = [
  243. 'shippingMethod' => 'flatrate_flatrate',
  244. ];
  245. $response = $this->graphQL($query, $variables, $headers);
  246. $response->assertSuccessful();
  247. $data = $response->json('data.createCheckoutShippingMethod.checkoutShippingMethod');
  248. $this->assertNotNull($data, 'checkout shipping method response is null');
  249. $this->assertArrayHasKey('success', $data);
  250. }
  251. /**
  252. * Set Payment Method (Guest)
  253. */
  254. public function test_set_payment_method(): void
  255. {
  256. $token = $this->getGuestCartToken();
  257. // First add product to cart, set address, and set shipping
  258. $this->addProductToCart($token);
  259. $this->setCheckoutAddress($token);
  260. $this->setShippingMethod($token);
  261. $headers = $this->guestHeaders($token);
  262. $query = <<<'GQL'
  263. mutation createCheckoutPaymentMethod(
  264. $paymentMethod: String!,
  265. $successUrl: String,
  266. $failureUrl: String,
  267. $cancelUrl: String
  268. ) {
  269. createCheckoutPaymentMethod(
  270. input: {
  271. paymentMethod: $paymentMethod,
  272. paymentSuccessUrl: $successUrl,
  273. paymentFailureUrl: $failureUrl,
  274. paymentCancelUrl: $cancelUrl
  275. }
  276. ) {
  277. checkoutPaymentMethod {
  278. success
  279. message
  280. paymentGatewayUrl
  281. paymentData
  282. }
  283. }
  284. }
  285. GQL;
  286. $variables = [
  287. 'paymentMethod' => 'moneytransfer',
  288. 'successUrl' => 'https://myapp.com/payment/success',
  289. 'failureUrl' => 'https://myapp.com/payment/failure',
  290. 'cancelUrl' => 'https://myapp.com/payment/cancel',
  291. ];
  292. $response = $this->graphQL($query, $variables, $headers);
  293. $response->assertSuccessful();
  294. $data = $response->json('data.createCheckoutPaymentMethod.checkoutPaymentMethod');
  295. $this->assertNotNull($data, 'checkout payment method response is null');
  296. $this->assertArrayHasKey('success', $data);
  297. }
  298. /**
  299. * Place Order (Guest)
  300. */
  301. public function test_place_order(): void
  302. {
  303. $token = $this->getGuestCartToken();
  304. // First add product to cart, set address, shipping and payment
  305. $this->addProductToCart($token);
  306. $this->setCheckoutAddress($token);
  307. $this->setShippingMethod($token);
  308. $this->setPaymentMethod($token);
  309. $headers = $this->guestHeaders($token);
  310. $query = <<<'GQL'
  311. mutation createCheckoutOrder {
  312. createCheckoutOrder(input:{}) {
  313. checkoutOrder {
  314. id
  315. orderId
  316. }
  317. }
  318. }
  319. GQL;
  320. $response = $this->graphQL($query, [], $headers);
  321. $response->assertSuccessful();
  322. $data = $response->json('data.createCheckoutOrder.checkoutOrder');
  323. $this->assertNotNull($data, 'checkout order response is null');
  324. $this->assertArrayHasKey('id', $data);
  325. $this->assertArrayHasKey('orderId', $data);
  326. }
  327. /**
  328. * Helper to set checkout address
  329. */
  330. private function setCheckoutAddress(string $token): void
  331. {
  332. $headers = $this->guestHeaders($token);
  333. $query = <<<'GQL'
  334. mutation createCheckoutAddress(
  335. $billingFirstName: String!
  336. $billingLastName: String!
  337. $billingEmail: String!
  338. $billingAddress: String!
  339. $billingCity: String!
  340. $billingCountry: String!
  341. $billingState: String!
  342. $billingPostcode: String!
  343. $billingPhoneNumber: String!
  344. $useForShipping: Boolean
  345. ) {
  346. createCheckoutAddress(
  347. input: {
  348. billingFirstName: $billingFirstName
  349. billingLastName: $billingLastName
  350. billingEmail: $billingEmail
  351. billingAddress: $billingAddress
  352. billingCity: $billingCity
  353. billingCountry: $billingCountry
  354. billingState: $billingState
  355. billingPostcode: $billingPostcode
  356. billingPhoneNumber: $billingPhoneNumber
  357. useForShipping: $useForShipping
  358. }
  359. ) {
  360. checkoutAddress {
  361. _id
  362. success
  363. }
  364. }
  365. }
  366. GQL;
  367. $variables = [
  368. 'billingFirstName' => 'John',
  369. 'billingLastName' => 'Doe',
  370. 'billingEmail' => 'john@example.com',
  371. 'billingAddress' => '123 Main St',
  372. 'billingCity' => 'Los Angeles',
  373. 'billingCountry' => 'IN',
  374. 'billingState' => 'UP',
  375. 'billingPostcode' => '201301',
  376. 'billingPhoneNumber' => '2125551234',
  377. 'useForShipping' => true,
  378. ];
  379. $this->graphQL($query, $variables, $headers);
  380. }
  381. /**
  382. * Helper to set shipping method
  383. */
  384. private function setShippingMethod(string $token): void
  385. {
  386. $headers = $this->guestHeaders($token);
  387. $query = <<<'GQL'
  388. mutation createCheckoutShippingMethod(
  389. $shippingMethod: String!
  390. ) {
  391. createCheckoutShippingMethod(
  392. input: {
  393. shippingMethod: $shippingMethod
  394. }
  395. ) {
  396. checkoutShippingMethod {
  397. success
  398. }
  399. }
  400. }
  401. GQL;
  402. $variables = [
  403. 'shippingMethod' => 'flatrate_flatrate',
  404. ];
  405. $this->graphQL($query, $variables, $headers);
  406. }
  407. /**
  408. * Helper to set payment method
  409. */
  410. private function setPaymentMethod(string $token): void
  411. {
  412. $headers = $this->guestHeaders($token);
  413. $query = <<<'GQL'
  414. mutation createCheckoutPaymentMethod(
  415. $paymentMethod: String!
  416. ) {
  417. createCheckoutPaymentMethod(
  418. input: {
  419. paymentMethod: $paymentMethod
  420. }
  421. ) {
  422. checkoutPaymentMethod {
  423. success
  424. }
  425. }
  426. }
  427. GQL;
  428. $variables = [
  429. 'paymentMethod' => 'moneytransfer',
  430. ];
  431. $this->graphQL($query, $variables, $headers);
  432. }
  433. }