order.e2e-spec.ts 26 KB

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