order.e2e-spec.ts 29 KB

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