order.e2e-spec.ts 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  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 sets shipping address', async () => {
  295. const address: CreateAddressInput = {
  296. fullName: 'name',
  297. company: 'company',
  298. streetLine1: '12 the street',
  299. streetLine2: 'line 2',
  300. city: 'foo',
  301. province: 'bar',
  302. postalCode: '123456',
  303. country: 'baz',
  304. phoneNumber: '4444444',
  305. };
  306. const result = await client.query(SET_SHIPPING_ADDRESS, {
  307. input: address,
  308. });
  309. expect(result.setOrderShippingAddress.shippingAddress).toEqual(address);
  310. });
  311. it('eligibleShippingMethods lists shipping methods', async () => {
  312. const result = await client.query(GET_ELIGIBLE_SHIPPING_METHODS);
  313. shippingMethods = result.eligibleShippingMethods;
  314. expect(shippingMethods).toEqual([
  315. { id: 'T_1', price: 500, description: 'Standard Shipping' },
  316. { id: 'T_2', price: 1000, description: 'Express Shipping' },
  317. ]);
  318. });
  319. it('shipping is initially unset', async () => {
  320. const result = await client.query(GET_ACTIVE_ORDER);
  321. expect(result.activeOrder.shipping).toEqual(0);
  322. expect(result.activeOrder.shippingMethod).toEqual(null);
  323. });
  324. it('setOrderShippingMethod sets the shipping method', async () => {
  325. const result = await client.query(SET_SHIPPING_METHOD, {
  326. id: shippingMethods[1].id,
  327. });
  328. const activeOrderResult = await client.query(GET_ACTIVE_ORDER);
  329. const order = activeOrderResult.activeOrder;
  330. expect(order.shipping).toBe(shippingMethods[1].price);
  331. expect(order.shippingMethod.id).toBe(shippingMethods[1].id);
  332. expect(order.shippingMethod.description).toBe(shippingMethods[1].description);
  333. });
  334. it('shipping method is preserved after adjustItemQuantity', async () => {
  335. const activeOrderResult = await client.query(GET_ACTIVE_ORDER);
  336. activeOrder = activeOrderResult.activeOrder;
  337. const result = await client.query(ADJUST_ITEM_QUENTITY, {
  338. orderItemId: activeOrder.lines[0].id,
  339. quantity: 10,
  340. });
  341. expect(result.adjustItemQuantity.shipping).toBe(shippingMethods[1].price);
  342. expect(result.adjustItemQuantity.shippingMethod.id).toBe(shippingMethods[1].id);
  343. expect(result.adjustItemQuantity.shippingMethod.description).toBe(
  344. shippingMethods[1].description,
  345. );
  346. });
  347. });
  348. describe('payment', () => {
  349. it('attempting add a Payment throws error when in AddingItems state', async () => {
  350. try {
  351. await client.query(ADD_PAYMENT, {
  352. input: {
  353. method: testPaymentMethod.code,
  354. metadata: {},
  355. },
  356. });
  357. fail('Should have thrown');
  358. } catch (err) {
  359. expect(err.message).toEqual(
  360. expect.stringContaining(
  361. `A Payment may only be added when Order is in "ArrangingPayment" state`,
  362. ),
  363. );
  364. }
  365. });
  366. it('transitions to the ArrangingPayment state', async () => {
  367. const result = await client.query(TRANSITION_TO_STATE, { state: 'ArrangingPayment' });
  368. expect(result.transitionOrderToState).toEqual({
  369. id: activeOrder.id,
  370. state: 'ArrangingPayment',
  371. });
  372. });
  373. it('attempting to add an item throws error when in ArrangingPayment state', async () => {
  374. try {
  375. const result = await client.query(ADD_ITEM_TO_ORDER, {
  376. productVariantId: 'T_4',
  377. quantity: 1,
  378. });
  379. fail('Should have thrown');
  380. } catch (err) {
  381. expect(err.message).toEqual(
  382. expect.stringContaining(
  383. `Order contents may only be modified when in the "AddingItems" state`,
  384. ),
  385. );
  386. }
  387. });
  388. it('attempting to modify item quantity throws error when in ArrangingPayment state', async () => {
  389. try {
  390. const result = await client.query(ADJUST_ITEM_QUENTITY, {
  391. orderItemId: activeOrder.lines[0].id,
  392. quantity: 12,
  393. });
  394. fail('Should have thrown');
  395. } catch (err) {
  396. expect(err.message).toEqual(
  397. expect.stringContaining(
  398. `Order contents may only be modified when in the "AddingItems" state`,
  399. ),
  400. );
  401. }
  402. });
  403. it('attempting to remove an item throws error when in ArrangingPayment state', async () => {
  404. try {
  405. const result = await client.query(REMOVE_ITEM_FROM_ORDER, {
  406. orderItemId: activeOrder.lines[0].id,
  407. });
  408. fail('Should have thrown');
  409. } catch (err) {
  410. expect(err.message).toEqual(
  411. expect.stringContaining(
  412. `Order contents may only be modified when in the "AddingItems" state`,
  413. ),
  414. );
  415. }
  416. });
  417. it('attempting to setOrderShippingMethod throws error when in ArrangingPayment state', async () => {
  418. const shippingMethodsResult = await client.query(GET_ELIGIBLE_SHIPPING_METHODS);
  419. const shippingMethods = shippingMethodsResult.eligibleShippingMethods;
  420. try {
  421. await client.query(SET_SHIPPING_METHOD, {
  422. id: shippingMethods[0].id,
  423. });
  424. fail('Should have thrown');
  425. } catch (err) {
  426. expect(err.message).toEqual(
  427. expect.stringContaining(
  428. `Order contents may only be modified when in the "AddingItems" state`,
  429. ),
  430. );
  431. }
  432. });
  433. it('adds a declined payment', async () => {
  434. const result = await client.query(ADD_PAYMENT, {
  435. input: {
  436. method: testFailingPaymentMethod.code,
  437. metadata: {
  438. foo: 'bar',
  439. },
  440. },
  441. });
  442. const payment = result.addPaymentToOrder.payments[0];
  443. expect(result.addPaymentToOrder.payments.length).toBe(1);
  444. expect(payment.method).toBe(testFailingPaymentMethod.code);
  445. expect(payment.state).toBe('Declined');
  446. expect(payment.transactionId).toBe(null);
  447. expect(payment.metadata).toEqual({
  448. foo: 'bar',
  449. });
  450. });
  451. it('adds a successful payment and transitions Order state', async () => {
  452. const result = await client.query(ADD_PAYMENT, {
  453. input: {
  454. method: testPaymentMethod.code,
  455. metadata: {
  456. baz: 'quux',
  457. },
  458. },
  459. });
  460. const payment = result.addPaymentToOrder.payments[0];
  461. expect(result.addPaymentToOrder.state).toBe('PaymentSettled');
  462. expect(result.addPaymentToOrder.active).toBe(false);
  463. expect(result.addPaymentToOrder.payments.length).toBe(1);
  464. expect(payment.method).toBe(testPaymentMethod.code);
  465. expect(payment.state).toBe('Settled');
  466. expect(payment.transactionId).toBe('12345');
  467. expect(payment.metadata).toEqual({
  468. baz: 'quux',
  469. });
  470. });
  471. });
  472. describe('orderByCode', () => {
  473. describe('immediately after Order is placed', () => {
  474. it('works when authenticated', async () => {
  475. const result = await client.query(GET_ORDER_BY_CODE, {
  476. code: activeOrder.code,
  477. });
  478. expect(result.orderByCode.id).toBe(activeOrder.id);
  479. });
  480. it('works when anonymous', async () => {
  481. await client.asAnonymousUser();
  482. const result = await client.query(GET_ORDER_BY_CODE, {
  483. code: activeOrder.code,
  484. });
  485. expect(result.orderByCode.id).toBe(activeOrder.id);
  486. });
  487. it(`throws error for another user's Order`, async () => {
  488. authenticatedUserEmailAddress = customers[1].emailAddress;
  489. await client.asUserWithCredentials(authenticatedUserEmailAddress, password);
  490. try {
  491. await client.query(GET_ORDER_BY_CODE, {
  492. code: activeOrder.code,
  493. });
  494. fail('Should have thrown');
  495. } catch (err) {
  496. expect(err.message).toEqual(
  497. expect.stringContaining(
  498. `You are not currently authorized to perform this action`,
  499. ),
  500. );
  501. }
  502. });
  503. });
  504. });
  505. });
  506. });
  507. const testPaymentMethod = new PaymentMethodHandler({
  508. code: 'test-payment-method',
  509. name: 'Test Payment Method',
  510. args: {},
  511. createPayment: (order, args, metadata) => {
  512. return {
  513. amount: order.total,
  514. state: 'Settled',
  515. transactionId: '12345',
  516. metadata,
  517. };
  518. },
  519. });
  520. const testFailingPaymentMethod = new PaymentMethodHandler({
  521. code: 'test-failing-payment-method',
  522. name: 'Test Failing Payment Method',
  523. args: {},
  524. createPayment: (order, args, metadata) => {
  525. return {
  526. amount: order.total,
  527. state: 'Declined',
  528. metadata,
  529. };
  530. },
  531. });
  532. const TEST_ORDER_FRAGMENT = gql`
  533. fragment TestOrderFragment on Order {
  534. id
  535. code
  536. state
  537. active
  538. lines {
  539. id
  540. quantity
  541. productVariant {
  542. id
  543. }
  544. }
  545. shipping
  546. shippingMethod {
  547. id
  548. code
  549. description
  550. }
  551. }
  552. `;
  553. const GET_ACTIVE_ORDER = gql`
  554. query {
  555. activeOrder {
  556. ...TestOrderFragment
  557. }
  558. }
  559. ${TEST_ORDER_FRAGMENT}
  560. `;
  561. const ADD_ITEM_TO_ORDER = gql`
  562. mutation AddItemToOrder($productVariantId: ID!, $quantity: Int!) {
  563. addItemToOrder(productVariantId: $productVariantId, quantity: $quantity) {
  564. ...TestOrderFragment
  565. }
  566. }
  567. ${TEST_ORDER_FRAGMENT}
  568. `;
  569. const ADJUST_ITEM_QUENTITY = gql`
  570. mutation AdjustItemQuantity($orderItemId: ID!, $quantity: Int!) {
  571. adjustItemQuantity(orderItemId: $orderItemId, quantity: $quantity) {
  572. ...TestOrderFragment
  573. }
  574. }
  575. ${TEST_ORDER_FRAGMENT}
  576. `;
  577. const REMOVE_ITEM_FROM_ORDER = gql`
  578. mutation RemoveItemFromOrder($orderItemId: ID!) {
  579. removeItemFromOrder(orderItemId: $orderItemId) {
  580. ...TestOrderFragment
  581. }
  582. }
  583. ${TEST_ORDER_FRAGMENT}
  584. `;
  585. const GET_NEXT_STATES = gql`
  586. query {
  587. nextOrderStates
  588. }
  589. `;
  590. const TRANSITION_TO_STATE = gql`
  591. mutation TransitionToState($state: String!) {
  592. transitionOrderToState(state: $state) {
  593. id
  594. state
  595. }
  596. }
  597. `;
  598. const GET_ELIGIBLE_SHIPPING_METHODS = gql`
  599. query {
  600. eligibleShippingMethods {
  601. id
  602. price
  603. description
  604. }
  605. }
  606. `;
  607. const SET_SHIPPING_ADDRESS = gql`
  608. mutation SetShippingAddress($input: CreateAddressInput!) {
  609. setOrderShippingAddress(input: $input) {
  610. shippingAddress {
  611. fullName
  612. company
  613. streetLine1
  614. streetLine2
  615. city
  616. province
  617. postalCode
  618. country
  619. phoneNumber
  620. }
  621. }
  622. }
  623. `;
  624. const SET_SHIPPING_METHOD = gql`
  625. mutation SetShippingMethod($id: ID!) {
  626. setOrderShippingMethod(shippingMethodId: $id) {
  627. shipping
  628. shippingMethod {
  629. id
  630. code
  631. description
  632. }
  633. }
  634. }
  635. `;
  636. const ADD_PAYMENT = gql`
  637. mutation AddPaymentToOrder($input: PaymentInput!) {
  638. addPaymentToOrder(input: $input) {
  639. ...TestOrderFragment
  640. payments {
  641. id
  642. transactionId
  643. method
  644. amount
  645. state
  646. metadata
  647. }
  648. }
  649. }
  650. ${TEST_ORDER_FRAGMENT}
  651. `;
  652. const SET_CUSTOMER = gql`
  653. mutation SetCustomerForOrder($input: CreateCustomerInput!) {
  654. setCustomerForOrder(input: $input) {
  655. id
  656. customer {
  657. id
  658. emailAddress
  659. firstName
  660. lastName
  661. }
  662. }
  663. }
  664. `;
  665. const GET_ORDER_BY_CODE = gql`
  666. query GetOrderByCode($code: String!) {
  667. orderByCode(code: $code) {
  668. ...TestOrderFragment
  669. }
  670. }
  671. ${TEST_ORDER_FRAGMENT}
  672. `;