order.e2e-spec.ts 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. import gql from 'graphql-tag';
  2. import { GET_CUSTOMER_LIST } from '../../admin-ui/src/app/data/definitions/customer-definitions';
  3. import { CreateAddressInput, GetCustomerList } from '../../shared/generated-types';
  4. import { PaymentMethodHandler } from '../src/config/payment-method/payment-method-handler';
  5. import { TEST_SETUP_TIMEOUT_MS } from './config/test-config';
  6. import { TestClient } from './test-client';
  7. import { TestServer } from './test-server';
  8. describe('Orders', () => {
  9. const client = new TestClient();
  10. const server = new TestServer();
  11. beforeAll(async () => {
  12. const token = await server.init(
  13. {
  14. productCount: 10,
  15. customerCount: 2,
  16. },
  17. {
  18. paymentOptions: {
  19. paymentMethodHandlers: [testPaymentMethod, testFailingPaymentMethod],
  20. },
  21. },
  22. );
  23. await client.init();
  24. }, TEST_SETUP_TIMEOUT_MS);
  25. afterAll(async () => {
  26. await server.destroy();
  27. });
  28. describe('as anonymous user', () => {
  29. let firstOrderItemId: string;
  30. let createdCustomerId: string;
  31. beforeAll(async () => {
  32. await client.asAnonymousUser();
  33. });
  34. it('addItemToOrder starts with no session token', () => {
  35. expect(client.getAuthToken()).toBe('');
  36. });
  37. it('activeOrder returns null before any items have been added', async () => {
  38. const result = await client.query(GET_ACTIVE_ORDER);
  39. expect(result.activeOrder).toBeNull();
  40. });
  41. it('activeOrder creates an anonymous session', () => {
  42. expect(client.getAuthToken()).not.toBe('');
  43. });
  44. it('addItemToOrder creates a new Order with an item', async () => {
  45. const result = await client.query(ADD_ITEM_TO_ORDER, {
  46. productVariantId: 'T_1',
  47. quantity: 1,
  48. });
  49. expect(result.addItemToOrder.lines.length).toBe(1);
  50. expect(result.addItemToOrder.lines[0].quantity).toBe(1);
  51. expect(result.addItemToOrder.lines[0].productVariant.id).toBe('T_1');
  52. expect(result.addItemToOrder.lines[0].id).toBe('T_1');
  53. firstOrderItemId = result.addItemToOrder.lines[0].id;
  54. });
  55. it('addItemToOrder errors with an invalid productVariantId', async () => {
  56. try {
  57. await client.query(ADD_ITEM_TO_ORDER, {
  58. productVariantId: 'T_999',
  59. quantity: 1,
  60. });
  61. fail('Should have thrown');
  62. } catch (err) {
  63. expect(err.message).toEqual(
  64. expect.stringContaining(`No ProductVariant with the id '999' could be found`),
  65. );
  66. }
  67. });
  68. it('addItemToOrder errors with a negative quantity', async () => {
  69. try {
  70. await client.query(ADD_ITEM_TO_ORDER, {
  71. productVariantId: 'T_999',
  72. quantity: -3,
  73. });
  74. fail('Should have thrown');
  75. } catch (err) {
  76. expect(err.message).toEqual(
  77. expect.stringContaining(`-3 is not a valid quantity for an OrderItem`),
  78. );
  79. }
  80. });
  81. it('addItemToOrder with an existing productVariantId adds quantity to the existing OrderLine', async () => {
  82. const result = await client.query(ADD_ITEM_TO_ORDER, {
  83. productVariantId: 'T_1',
  84. quantity: 2,
  85. });
  86. expect(result.addItemToOrder.lines.length).toBe(1);
  87. expect(result.addItemToOrder.lines[0].quantity).toBe(3);
  88. });
  89. it('adjustItemQuantity adjusts the quantity', async () => {
  90. const result = await client.query(ADJUST_ITEM_QUENTITY, {
  91. orderItemId: firstOrderItemId,
  92. quantity: 50,
  93. });
  94. expect(result.adjustItemQuantity.lines.length).toBe(1);
  95. expect(result.adjustItemQuantity.lines[0].quantity).toBe(50);
  96. });
  97. it('adjustItemQuantity errors with a negative quantity', async () => {
  98. try {
  99. await client.query(ADJUST_ITEM_QUENTITY, {
  100. orderItemId: firstOrderItemId,
  101. quantity: -3,
  102. });
  103. fail('Should have thrown');
  104. } catch (err) {
  105. expect(err.message).toEqual(
  106. expect.stringContaining(`-3 is not a valid quantity for an OrderItem`),
  107. );
  108. }
  109. });
  110. it('adjustItemQuantity errors with an invalid orderItemId', async () => {
  111. try {
  112. await client.query(ADJUST_ITEM_QUENTITY, {
  113. orderItemId: 'T_999',
  114. quantity: 5,
  115. });
  116. fail('Should have thrown');
  117. } catch (err) {
  118. expect(err.message).toEqual(
  119. expect.stringContaining(`This order does not contain an OrderLine with the id 999`),
  120. );
  121. }
  122. });
  123. it('removeItemFromOrder removes the correct item', async () => {
  124. const result1 = await client.query(ADD_ITEM_TO_ORDER, {
  125. productVariantId: 'T_3',
  126. quantity: 3,
  127. });
  128. expect(result1.addItemToOrder.lines.length).toBe(2);
  129. expect(result1.addItemToOrder.lines.map(i => i.productVariant.id)).toEqual(['T_1', 'T_3']);
  130. const result2 = await client.query(REMOVE_ITEM_FROM_ORDER, {
  131. orderItemId: firstOrderItemId,
  132. });
  133. expect(result2.removeItemFromOrder.lines.length).toBe(1);
  134. expect(result2.removeItemFromOrder.lines.map(i => i.productVariant.id)).toEqual(['T_3']);
  135. });
  136. it('removeItemFromOrder errors with an invalid orderItemId', async () => {
  137. try {
  138. await client.query(REMOVE_ITEM_FROM_ORDER, {
  139. orderItemId: 'T_999',
  140. });
  141. fail('Should have thrown');
  142. } catch (err) {
  143. expect(err.message).toEqual(
  144. expect.stringContaining(`This order does not contain an OrderLine with the id 999`),
  145. );
  146. }
  147. });
  148. it('nextOrderStates returns next valid states', async () => {
  149. const result = await client.query(gql`
  150. query {
  151. nextOrderStates
  152. }
  153. `);
  154. expect(result.nextOrderStates).toEqual(['ArrangingPayment']);
  155. });
  156. it('transitionOrderToState throws for an invalid state', async () => {
  157. try {
  158. await client.query(TRANSITION_TO_STATE, { state: 'Completed' });
  159. fail('Should have thrown');
  160. } catch (err) {
  161. expect(err.message).toEqual(
  162. expect.stringContaining(`Cannot transition Order from "AddingItems" to "Completed"`),
  163. );
  164. }
  165. });
  166. it('attempting to transition to ArrangingPayment throws when Order has no Customer', async () => {
  167. try {
  168. await client.query(TRANSITION_TO_STATE, { state: 'ArrangingPayment' });
  169. fail('Should have thrown');
  170. } catch (err) {
  171. expect(err.message).toEqual(
  172. expect.stringContaining(
  173. `Cannot transition Order to the "ArrangingShipping" state without Customer details`,
  174. ),
  175. );
  176. }
  177. });
  178. it('setCustomerForOrder creates a new Customer and associates it with the Order', async () => {
  179. const result = await client.query(SET_CUSTOMER, {
  180. input: {
  181. emailAddress: 'test@test.com',
  182. firstName: 'Test',
  183. lastName: 'Person',
  184. },
  185. });
  186. const customer = result.setCustomerForOrder.customer;
  187. expect(customer.firstName).toBe('Test');
  188. expect(customer.lastName).toBe('Person');
  189. expect(customer.emailAddress).toBe('test@test.com');
  190. createdCustomerId = customer.id;
  191. });
  192. it('setCustomerForOrder updates the existing customer if Customer already set', async () => {
  193. const result = await client.query(SET_CUSTOMER, {
  194. input: {
  195. emailAddress: 'test@test.com',
  196. firstName: 'Changed',
  197. lastName: 'Person',
  198. },
  199. });
  200. const customer = result.setCustomerForOrder.customer;
  201. expect(customer.firstName).toBe('Changed');
  202. expect(customer.lastName).toBe('Person');
  203. expect(customer.emailAddress).toBe('test@test.com');
  204. expect(customer.id).toBe(createdCustomerId);
  205. });
  206. it('can transition to ArrangingPayment once Customer has been set', async () => {
  207. const result = await client.query(TRANSITION_TO_STATE, { state: 'ArrangingPayment' });
  208. expect(result.transitionOrderToState).toEqual({ id: 'T_1', state: 'ArrangingPayment' });
  209. });
  210. });
  211. describe('as authenticated user', () => {
  212. let firstOrderItemId: string;
  213. let activeOrder: any;
  214. let authenticatedUserEmailAddress: string;
  215. let customers: GetCustomerList.Items[];
  216. const password = 'test';
  217. beforeAll(async () => {
  218. await client.asSuperAdmin();
  219. const result = await client.query<GetCustomerList.Query, GetCustomerList.Variables>(
  220. GET_CUSTOMER_LIST,
  221. {
  222. options: {
  223. take: 2,
  224. },
  225. },
  226. );
  227. customers = result.customers.items;
  228. authenticatedUserEmailAddress = customers[0].emailAddress;
  229. await client.asUserWithCredentials(authenticatedUserEmailAddress, password);
  230. });
  231. it('activeOrder returns null before any items have been added', async () => {
  232. const result = await client.query(GET_ACTIVE_ORDER);
  233. expect(result.activeOrder).toBeNull();
  234. });
  235. it('addItemToOrder creates a new Order with an item', async () => {
  236. const result = await client.query(ADD_ITEM_TO_ORDER, {
  237. productVariantId: 'T_1',
  238. quantity: 1,
  239. });
  240. expect(result.addItemToOrder.lines.length).toBe(1);
  241. expect(result.addItemToOrder.lines[0].quantity).toBe(1);
  242. expect(result.addItemToOrder.lines[0].productVariant.id).toBe('T_1');
  243. activeOrder = result.addItemToOrder;
  244. firstOrderItemId = result.addItemToOrder.lines[0].id;
  245. });
  246. it('activeOrder returns order after item has been added', async () => {
  247. const result = await client.query(GET_ACTIVE_ORDER);
  248. expect(result.activeOrder.id).toBe(activeOrder.id);
  249. expect(result.activeOrder.state).toBe('AddingItems');
  250. });
  251. it('addItemToOrder with an existing productVariantId adds quantity to the existing OrderLine', async () => {
  252. const result = await client.query(ADD_ITEM_TO_ORDER, {
  253. productVariantId: 'T_1',
  254. quantity: 2,
  255. });
  256. expect(result.addItemToOrder.lines.length).toBe(1);
  257. expect(result.addItemToOrder.lines[0].quantity).toBe(3);
  258. });
  259. it('adjustItemQuantity adjusts the quantity', async () => {
  260. const result = await client.query(ADJUST_ITEM_QUENTITY, {
  261. orderItemId: firstOrderItemId,
  262. quantity: 50,
  263. });
  264. expect(result.adjustItemQuantity.lines.length).toBe(1);
  265. expect(result.adjustItemQuantity.lines[0].quantity).toBe(50);
  266. });
  267. it('removeItemFromOrder removes the correct item', async () => {
  268. const result1 = await client.query(ADD_ITEM_TO_ORDER, {
  269. productVariantId: 'T_3',
  270. quantity: 3,
  271. });
  272. expect(result1.addItemToOrder.lines.length).toBe(2);
  273. expect(result1.addItemToOrder.lines.map(i => i.productVariant.id)).toEqual(['T_1', 'T_3']);
  274. const result2 = await client.query(REMOVE_ITEM_FROM_ORDER, {
  275. orderItemId: firstOrderItemId,
  276. });
  277. expect(result2.removeItemFromOrder.lines.length).toBe(1);
  278. expect(result2.removeItemFromOrder.lines.map(i => i.productVariant.id)).toEqual(['T_3']);
  279. });
  280. it('nextOrderStates returns next valid states', async () => {
  281. const result = await client.query(GET_NEXT_STATES);
  282. expect(result.nextOrderStates).toEqual(['ArrangingPayment']);
  283. });
  284. it('logging out and back in again resumes the last active order', async () => {
  285. await client.asAnonymousUser();
  286. const result1 = await client.query(GET_ACTIVE_ORDER);
  287. expect(result1.activeOrder).toBeNull();
  288. await client.asUserWithCredentials(authenticatedUserEmailAddress, password);
  289. const result2 = await client.query(GET_ACTIVE_ORDER);
  290. expect(result2.activeOrder.id).toBe(activeOrder.id);
  291. });
  292. describe('shipping', () => {
  293. let shippingMethods: any;
  294. it('setOrderShippingAddress throws with invalid countryCode', async () => {
  295. const address: CreateAddressInput = {
  296. streetLine1: '12 the street',
  297. countryCode: 'INVALID',
  298. };
  299. try {
  300. await client.query(SET_SHIPPING_ADDRESS, {
  301. input: address,
  302. });
  303. fail('Should have thrown');
  304. } catch (err) {
  305. expect(err.message).toEqual(
  306. expect.stringContaining(`The countryCode "INVALID" was not recognized`),
  307. );
  308. }
  309. });
  310. it('setOrderShippingAddress sets shipping address', async () => {
  311. const address: CreateAddressInput = {
  312. fullName: 'name',
  313. company: 'company',
  314. streetLine1: '12 the street',
  315. streetLine2: 'line 2',
  316. city: 'foo',
  317. province: 'bar',
  318. postalCode: '123456',
  319. countryCode: 'US',
  320. phoneNumber: '4444444',
  321. };
  322. const result = await client.query(SET_SHIPPING_ADDRESS, {
  323. input: address,
  324. });
  325. expect(result.setOrderShippingAddress.shippingAddress).toEqual({
  326. fullName: 'name',
  327. company: 'company',
  328. streetLine1: '12 the street',
  329. streetLine2: 'line 2',
  330. city: 'foo',
  331. province: 'bar',
  332. postalCode: '123456',
  333. country: 'United States of America',
  334. phoneNumber: '4444444',
  335. });
  336. });
  337. it('eligibleShippingMethods lists shipping methods', async () => {
  338. const result = await client.query(GET_ELIGIBLE_SHIPPING_METHODS);
  339. shippingMethods = result.eligibleShippingMethods;
  340. expect(shippingMethods).toEqual([
  341. { id: 'T_1', price: 500, description: 'Standard Shipping' },
  342. { id: 'T_2', price: 1000, description: 'Express Shipping' },
  343. ]);
  344. });
  345. it('shipping is initially unset', async () => {
  346. const result = await client.query(GET_ACTIVE_ORDER);
  347. expect(result.activeOrder.shipping).toEqual(0);
  348. expect(result.activeOrder.shippingMethod).toEqual(null);
  349. });
  350. it('setOrderShippingMethod sets the shipping method', async () => {
  351. const result = await client.query(SET_SHIPPING_METHOD, {
  352. id: shippingMethods[1].id,
  353. });
  354. const activeOrderResult = await client.query(GET_ACTIVE_ORDER);
  355. const order = activeOrderResult.activeOrder;
  356. expect(order.shipping).toBe(shippingMethods[1].price);
  357. expect(order.shippingMethod.id).toBe(shippingMethods[1].id);
  358. expect(order.shippingMethod.description).toBe(shippingMethods[1].description);
  359. });
  360. it('shipping method is preserved after adjustItemQuantity', async () => {
  361. const activeOrderResult = await client.query(GET_ACTIVE_ORDER);
  362. activeOrder = activeOrderResult.activeOrder;
  363. const result = await client.query(ADJUST_ITEM_QUENTITY, {
  364. orderItemId: activeOrder.lines[0].id,
  365. quantity: 10,
  366. });
  367. expect(result.adjustItemQuantity.shipping).toBe(shippingMethods[1].price);
  368. expect(result.adjustItemQuantity.shippingMethod.id).toBe(shippingMethods[1].id);
  369. expect(result.adjustItemQuantity.shippingMethod.description).toBe(
  370. shippingMethods[1].description,
  371. );
  372. });
  373. });
  374. describe('payment', () => {
  375. it('attempting add a Payment throws error when in AddingItems state', async () => {
  376. try {
  377. await client.query(ADD_PAYMENT, {
  378. input: {
  379. method: testPaymentMethod.code,
  380. metadata: {},
  381. },
  382. });
  383. fail('Should have thrown');
  384. } catch (err) {
  385. expect(err.message).toEqual(
  386. expect.stringContaining(
  387. `A Payment may only be added when Order is in "ArrangingPayment" state`,
  388. ),
  389. );
  390. }
  391. });
  392. it('transitions to the ArrangingPayment state', async () => {
  393. const result = await client.query(TRANSITION_TO_STATE, { state: 'ArrangingPayment' });
  394. expect(result.transitionOrderToState).toEqual({
  395. id: activeOrder.id,
  396. state: 'ArrangingPayment',
  397. });
  398. });
  399. it('attempting to add an item throws error when in ArrangingPayment state', async () => {
  400. try {
  401. const result = await client.query(ADD_ITEM_TO_ORDER, {
  402. productVariantId: 'T_4',
  403. quantity: 1,
  404. });
  405. fail('Should have thrown');
  406. } catch (err) {
  407. expect(err.message).toEqual(
  408. expect.stringContaining(
  409. `Order contents may only be modified when in the "AddingItems" state`,
  410. ),
  411. );
  412. }
  413. });
  414. it('attempting to modify item quantity throws error when in ArrangingPayment state', async () => {
  415. try {
  416. const result = await client.query(ADJUST_ITEM_QUENTITY, {
  417. orderItemId: activeOrder.lines[0].id,
  418. quantity: 12,
  419. });
  420. fail('Should have thrown');
  421. } catch (err) {
  422. expect(err.message).toEqual(
  423. expect.stringContaining(
  424. `Order contents may only be modified when in the "AddingItems" state`,
  425. ),
  426. );
  427. }
  428. });
  429. it('attempting to remove an item throws error when in ArrangingPayment state', async () => {
  430. try {
  431. const result = await client.query(REMOVE_ITEM_FROM_ORDER, {
  432. orderItemId: activeOrder.lines[0].id,
  433. });
  434. fail('Should have thrown');
  435. } catch (err) {
  436. expect(err.message).toEqual(
  437. expect.stringContaining(
  438. `Order contents may only be modified when in the "AddingItems" state`,
  439. ),
  440. );
  441. }
  442. });
  443. it('attempting to setOrderShippingMethod throws error when in ArrangingPayment state', async () => {
  444. const shippingMethodsResult = await client.query(GET_ELIGIBLE_SHIPPING_METHODS);
  445. const shippingMethods = shippingMethodsResult.eligibleShippingMethods;
  446. try {
  447. await client.query(SET_SHIPPING_METHOD, {
  448. id: shippingMethods[0].id,
  449. });
  450. fail('Should have thrown');
  451. } catch (err) {
  452. expect(err.message).toEqual(
  453. expect.stringContaining(
  454. `Order contents may only be modified when in the "AddingItems" state`,
  455. ),
  456. );
  457. }
  458. });
  459. it('adds a declined payment', async () => {
  460. const result = await client.query(ADD_PAYMENT, {
  461. input: {
  462. method: testFailingPaymentMethod.code,
  463. metadata: {
  464. foo: 'bar',
  465. },
  466. },
  467. });
  468. const payment = result.addPaymentToOrder.payments[0];
  469. expect(result.addPaymentToOrder.payments.length).toBe(1);
  470. expect(payment.method).toBe(testFailingPaymentMethod.code);
  471. expect(payment.state).toBe('Declined');
  472. expect(payment.transactionId).toBe(null);
  473. expect(payment.metadata).toEqual({
  474. foo: 'bar',
  475. });
  476. });
  477. it('adds a successful payment and transitions Order state', async () => {
  478. const result = await client.query(ADD_PAYMENT, {
  479. input: {
  480. method: testPaymentMethod.code,
  481. metadata: {
  482. baz: 'quux',
  483. },
  484. },
  485. });
  486. const payment = result.addPaymentToOrder.payments[0];
  487. expect(result.addPaymentToOrder.state).toBe('PaymentSettled');
  488. expect(result.addPaymentToOrder.active).toBe(false);
  489. expect(result.addPaymentToOrder.payments.length).toBe(1);
  490. expect(payment.method).toBe(testPaymentMethod.code);
  491. expect(payment.state).toBe('Settled');
  492. expect(payment.transactionId).toBe('12345');
  493. expect(payment.metadata).toEqual({
  494. baz: 'quux',
  495. });
  496. });
  497. });
  498. describe('orderByCode', () => {
  499. describe('immediately after Order is placed', () => {
  500. it('works when authenticated', async () => {
  501. const result = await client.query(GET_ORDER_BY_CODE, {
  502. code: activeOrder.code,
  503. });
  504. expect(result.orderByCode.id).toBe(activeOrder.id);
  505. });
  506. it('works when anonymous', async () => {
  507. await client.asAnonymousUser();
  508. const result = await client.query(GET_ORDER_BY_CODE, {
  509. code: activeOrder.code,
  510. });
  511. expect(result.orderByCode.id).toBe(activeOrder.id);
  512. });
  513. it(`throws error for another user's Order`, async () => {
  514. authenticatedUserEmailAddress = customers[1].emailAddress;
  515. await client.asUserWithCredentials(authenticatedUserEmailAddress, password);
  516. try {
  517. await client.query(GET_ORDER_BY_CODE, {
  518. code: activeOrder.code,
  519. });
  520. fail('Should have thrown');
  521. } catch (err) {
  522. expect(err.message).toEqual(
  523. expect.stringContaining(
  524. `You are not currently authorized to perform this action`,
  525. ),
  526. );
  527. }
  528. });
  529. });
  530. });
  531. });
  532. });
  533. const testPaymentMethod = new PaymentMethodHandler({
  534. code: 'test-payment-method',
  535. name: 'Test Payment Method',
  536. args: {},
  537. createPayment: (order, args, metadata) => {
  538. return {
  539. amount: order.total,
  540. state: 'Settled',
  541. transactionId: '12345',
  542. metadata,
  543. };
  544. },
  545. });
  546. const testFailingPaymentMethod = new PaymentMethodHandler({
  547. code: 'test-failing-payment-method',
  548. name: 'Test Failing Payment Method',
  549. args: {},
  550. createPayment: (order, args, metadata) => {
  551. return {
  552. amount: order.total,
  553. state: 'Declined',
  554. metadata,
  555. };
  556. },
  557. });
  558. const TEST_ORDER_FRAGMENT = gql`
  559. fragment TestOrderFragment on Order {
  560. id
  561. code
  562. state
  563. active
  564. lines {
  565. id
  566. quantity
  567. productVariant {
  568. id
  569. }
  570. }
  571. shipping
  572. shippingMethod {
  573. id
  574. code
  575. description
  576. }
  577. }
  578. `;
  579. const GET_ACTIVE_ORDER = gql`
  580. query {
  581. activeOrder {
  582. ...TestOrderFragment
  583. }
  584. }
  585. ${TEST_ORDER_FRAGMENT}
  586. `;
  587. const ADD_ITEM_TO_ORDER = gql`
  588. mutation AddItemToOrder($productVariantId: ID!, $quantity: Int!) {
  589. addItemToOrder(productVariantId: $productVariantId, quantity: $quantity) {
  590. ...TestOrderFragment
  591. }
  592. }
  593. ${TEST_ORDER_FRAGMENT}
  594. `;
  595. const ADJUST_ITEM_QUENTITY = gql`
  596. mutation AdjustItemQuantity($orderItemId: ID!, $quantity: Int!) {
  597. adjustItemQuantity(orderItemId: $orderItemId, quantity: $quantity) {
  598. ...TestOrderFragment
  599. }
  600. }
  601. ${TEST_ORDER_FRAGMENT}
  602. `;
  603. const REMOVE_ITEM_FROM_ORDER = gql`
  604. mutation RemoveItemFromOrder($orderItemId: ID!) {
  605. removeItemFromOrder(orderItemId: $orderItemId) {
  606. ...TestOrderFragment
  607. }
  608. }
  609. ${TEST_ORDER_FRAGMENT}
  610. `;
  611. const GET_NEXT_STATES = gql`
  612. query {
  613. nextOrderStates
  614. }
  615. `;
  616. const TRANSITION_TO_STATE = gql`
  617. mutation TransitionToState($state: String!) {
  618. transitionOrderToState(state: $state) {
  619. id
  620. state
  621. }
  622. }
  623. `;
  624. const GET_ELIGIBLE_SHIPPING_METHODS = gql`
  625. query {
  626. eligibleShippingMethods {
  627. id
  628. price
  629. description
  630. }
  631. }
  632. `;
  633. const SET_SHIPPING_ADDRESS = gql`
  634. mutation SetShippingAddress($input: CreateAddressInput!) {
  635. setOrderShippingAddress(input: $input) {
  636. shippingAddress {
  637. fullName
  638. company
  639. streetLine1
  640. streetLine2
  641. city
  642. province
  643. postalCode
  644. country
  645. phoneNumber
  646. }
  647. }
  648. }
  649. `;
  650. const SET_SHIPPING_METHOD = gql`
  651. mutation SetShippingMethod($id: ID!) {
  652. setOrderShippingMethod(shippingMethodId: $id) {
  653. shipping
  654. shippingMethod {
  655. id
  656. code
  657. description
  658. }
  659. }
  660. }
  661. `;
  662. const ADD_PAYMENT = gql`
  663. mutation AddPaymentToOrder($input: PaymentInput!) {
  664. addPaymentToOrder(input: $input) {
  665. ...TestOrderFragment
  666. payments {
  667. id
  668. transactionId
  669. method
  670. amount
  671. state
  672. metadata
  673. }
  674. }
  675. }
  676. ${TEST_ORDER_FRAGMENT}
  677. `;
  678. const SET_CUSTOMER = gql`
  679. mutation SetCustomerForOrder($input: CreateCustomerInput!) {
  680. setCustomerForOrder(input: $input) {
  681. id
  682. customer {
  683. id
  684. emailAddress
  685. firstName
  686. lastName
  687. }
  688. }
  689. }
  690. `;
  691. const GET_ORDER_BY_CODE = gql`
  692. query GetOrderByCode($code: String!) {
  693. orderByCode(code: $code) {
  694. ...TestOrderFragment
  695. }
  696. }
  697. ${TEST_ORDER_FRAGMENT}
  698. `;