CustomerCheckoutTest.php 16 KB

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