shipping-method.e2e-spec.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. /* tslint:disable:no-non-null-assertion */
  2. import {
  3. defaultShippingCalculator,
  4. defaultShippingEligibilityChecker,
  5. ShippingCalculator,
  6. } from '@vendure/core';
  7. import { createTestEnvironment } from '@vendure/testing';
  8. import gql from 'graphql-tag';
  9. import path from 'path';
  10. import { initialData } from '../../../e2e-common/e2e-initial-data';
  11. import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
  12. import { manualFulfillmentHandler } from '../src/config/fulfillment/manual-fulfillment-handler';
  13. import { SHIPPING_METHOD_FRAGMENT } from './graphql/fragments';
  14. import {
  15. CreateShippingMethod,
  16. DeleteShippingMethod,
  17. DeletionResult,
  18. GetCalculators,
  19. GetEligibilityCheckers,
  20. GetShippingMethod,
  21. GetShippingMethodList,
  22. LanguageCode,
  23. TestEligibleMethods,
  24. TestShippingMethod,
  25. UpdateShippingMethod,
  26. } from './graphql/generated-e2e-admin-types';
  27. import { CREATE_SHIPPING_METHOD } from './graphql/shared-definitions';
  28. const TEST_METADATA = {
  29. foo: 'bar',
  30. baz: [1, 2, 3],
  31. };
  32. const calculatorWithMetadata = new ShippingCalculator({
  33. code: 'calculator-with-metadata',
  34. description: [{ languageCode: LanguageCode.en, value: 'Has metadata' }],
  35. args: {},
  36. calculate: () => {
  37. return {
  38. price: 100,
  39. priceWithTax: 100,
  40. metadata: TEST_METADATA,
  41. };
  42. },
  43. });
  44. describe('ShippingMethod resolver', () => {
  45. const { server, adminClient, shopClient } = createTestEnvironment({
  46. ...testConfig,
  47. shippingOptions: {
  48. shippingEligibilityCheckers: [defaultShippingEligibilityChecker],
  49. shippingCalculators: [defaultShippingCalculator, calculatorWithMetadata],
  50. },
  51. });
  52. beforeAll(async () => {
  53. await server.init({
  54. initialData,
  55. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-full.csv'),
  56. customerCount: 1,
  57. });
  58. await adminClient.asSuperAdmin();
  59. }, TEST_SETUP_TIMEOUT_MS);
  60. afterAll(async () => {
  61. await server.destroy();
  62. });
  63. it('shippingEligibilityCheckers', async () => {
  64. const { shippingEligibilityCheckers } = await adminClient.query<GetEligibilityCheckers.Query>(
  65. GET_ELIGIBILITY_CHECKERS,
  66. );
  67. expect(shippingEligibilityCheckers).toEqual([
  68. {
  69. args: [
  70. {
  71. description: 'Order is eligible only if its total is greater or equal to this value',
  72. label: 'Minimum order value',
  73. name: 'orderMinimum',
  74. type: 'int',
  75. ui: {
  76. component: 'currency-form-input',
  77. },
  78. },
  79. ],
  80. code: 'default-shipping-eligibility-checker',
  81. description: 'Default Shipping Eligibility Checker',
  82. },
  83. ]);
  84. });
  85. it('shippingCalculators', async () => {
  86. const { shippingCalculators } = await adminClient.query<GetCalculators.Query>(GET_CALCULATORS);
  87. expect(shippingCalculators).toEqual([
  88. {
  89. args: [
  90. {
  91. ui: {
  92. component: 'currency-form-input',
  93. },
  94. description: null,
  95. label: 'Shipping price',
  96. name: 'rate',
  97. type: 'int',
  98. },
  99. {
  100. ui: {
  101. component: 'number-form-input',
  102. suffix: '%',
  103. },
  104. description: null,
  105. label: 'Tax rate',
  106. name: 'taxRate',
  107. type: 'int',
  108. },
  109. ],
  110. code: 'default-shipping-calculator',
  111. description: 'Default Flat-Rate Shipping Calculator',
  112. },
  113. {
  114. args: [],
  115. code: 'calculator-with-metadata',
  116. description: 'Has metadata',
  117. },
  118. ]);
  119. });
  120. it('shippingMethods', async () => {
  121. const { shippingMethods } = await adminClient.query<GetShippingMethodList.Query>(
  122. GET_SHIPPING_METHOD_LIST,
  123. );
  124. expect(shippingMethods.totalItems).toEqual(2);
  125. expect(shippingMethods.items[0].code).toBe('standard-shipping');
  126. expect(shippingMethods.items[1].code).toBe('express-shipping');
  127. });
  128. it('shippingMethod', async () => {
  129. const { shippingMethod } = await adminClient.query<
  130. GetShippingMethod.Query,
  131. GetShippingMethod.Variables
  132. >(GET_SHIPPING_METHOD, {
  133. id: 'T_1',
  134. });
  135. expect(shippingMethod!.code).toBe('standard-shipping');
  136. });
  137. it('createShippingMethod', async () => {
  138. const { createShippingMethod } = await adminClient.query<
  139. CreateShippingMethod.Mutation,
  140. CreateShippingMethod.Variables
  141. >(CREATE_SHIPPING_METHOD, {
  142. input: {
  143. code: 'new-method',
  144. fulfillmentHandler: manualFulfillmentHandler.code,
  145. checker: {
  146. code: defaultShippingEligibilityChecker.code,
  147. arguments: [
  148. {
  149. name: 'orderMinimum',
  150. value: '0',
  151. },
  152. ],
  153. },
  154. calculator: {
  155. code: calculatorWithMetadata.code,
  156. arguments: [],
  157. },
  158. translations: [{ languageCode: LanguageCode.en, name: 'new method', description: '' }],
  159. },
  160. });
  161. expect(createShippingMethod).toEqual({
  162. id: 'T_3',
  163. code: 'new-method',
  164. name: 'new method',
  165. description: '',
  166. calculator: {
  167. code: 'calculator-with-metadata',
  168. },
  169. checker: {
  170. code: 'default-shipping-eligibility-checker',
  171. },
  172. });
  173. });
  174. it('testShippingMethod', async () => {
  175. const { testShippingMethod } = await adminClient.query<
  176. TestShippingMethod.Query,
  177. TestShippingMethod.Variables
  178. >(TEST_SHIPPING_METHOD, {
  179. input: {
  180. calculator: {
  181. code: calculatorWithMetadata.code,
  182. arguments: [],
  183. },
  184. checker: {
  185. code: defaultShippingEligibilityChecker.code,
  186. arguments: [
  187. {
  188. name: 'orderMinimum',
  189. value: '0',
  190. },
  191. ],
  192. },
  193. lines: [{ productVariantId: 'T_1', quantity: 1 }],
  194. shippingAddress: {
  195. streetLine1: '',
  196. countryCode: 'GB',
  197. },
  198. },
  199. });
  200. expect(testShippingMethod).toEqual({
  201. eligible: true,
  202. quote: {
  203. price: 100,
  204. priceWithTax: 100,
  205. metadata: TEST_METADATA,
  206. },
  207. });
  208. });
  209. it('testEligibleShippingMethods', async () => {
  210. const { testEligibleShippingMethods } = await adminClient.query<
  211. TestEligibleMethods.Query,
  212. TestEligibleMethods.Variables
  213. >(TEST_ELIGIBLE_SHIPPING_METHODS, {
  214. input: {
  215. lines: [{ productVariantId: 'T_1', quantity: 1 }],
  216. shippingAddress: {
  217. streetLine1: '',
  218. countryCode: 'GB',
  219. },
  220. },
  221. });
  222. expect(testEligibleShippingMethods).toEqual([
  223. {
  224. id: 'T_3',
  225. name: 'new method',
  226. description: '',
  227. price: 100,
  228. priceWithTax: 100,
  229. metadata: TEST_METADATA,
  230. },
  231. {
  232. id: 'T_1',
  233. name: 'Standard Shipping',
  234. description: '',
  235. price: 500,
  236. priceWithTax: 500,
  237. metadata: null,
  238. },
  239. {
  240. id: 'T_2',
  241. name: 'Express Shipping',
  242. description: '',
  243. price: 1000,
  244. priceWithTax: 1000,
  245. metadata: null,
  246. },
  247. ]);
  248. });
  249. it('updateShippingMethod', async () => {
  250. const { updateShippingMethod } = await adminClient.query<
  251. UpdateShippingMethod.Mutation,
  252. UpdateShippingMethod.Variables
  253. >(UPDATE_SHIPPING_METHOD, {
  254. input: {
  255. id: 'T_3',
  256. translations: [{ languageCode: LanguageCode.en, name: 'changed method', description: '' }],
  257. },
  258. });
  259. expect(updateShippingMethod.name).toBe('changed method');
  260. });
  261. it('deleteShippingMethod', async () => {
  262. const listResult1 = await adminClient.query<GetShippingMethodList.Query>(GET_SHIPPING_METHOD_LIST);
  263. expect(listResult1.shippingMethods.items.map(i => i.id)).toEqual(['T_1', 'T_2', 'T_3']);
  264. const { deleteShippingMethod } = await adminClient.query<
  265. DeleteShippingMethod.Mutation,
  266. DeleteShippingMethod.Variables
  267. >(DELETE_SHIPPING_METHOD, {
  268. id: 'T_3',
  269. });
  270. expect(deleteShippingMethod).toEqual({
  271. result: DeletionResult.DELETED,
  272. message: null,
  273. });
  274. const listResult2 = await adminClient.query<GetShippingMethodList.Query>(GET_SHIPPING_METHOD_LIST);
  275. expect(listResult2.shippingMethods.items.map(i => i.id)).toEqual(['T_1', 'T_2']);
  276. });
  277. });
  278. const GET_SHIPPING_METHOD_LIST = gql`
  279. query GetShippingMethodList {
  280. shippingMethods {
  281. items {
  282. ...ShippingMethod
  283. }
  284. totalItems
  285. }
  286. }
  287. ${SHIPPING_METHOD_FRAGMENT}
  288. `;
  289. const GET_SHIPPING_METHOD = gql`
  290. query GetShippingMethod($id: ID!) {
  291. shippingMethod(id: $id) {
  292. ...ShippingMethod
  293. }
  294. }
  295. ${SHIPPING_METHOD_FRAGMENT}
  296. `;
  297. const UPDATE_SHIPPING_METHOD = gql`
  298. mutation UpdateShippingMethod($input: UpdateShippingMethodInput!) {
  299. updateShippingMethod(input: $input) {
  300. ...ShippingMethod
  301. }
  302. }
  303. ${SHIPPING_METHOD_FRAGMENT}
  304. `;
  305. const DELETE_SHIPPING_METHOD = gql`
  306. mutation DeleteShippingMethod($id: ID!) {
  307. deleteShippingMethod(id: $id) {
  308. result
  309. message
  310. }
  311. }
  312. `;
  313. const GET_ELIGIBILITY_CHECKERS = gql`
  314. query GetEligibilityCheckers {
  315. shippingEligibilityCheckers {
  316. code
  317. description
  318. args {
  319. name
  320. type
  321. description
  322. label
  323. ui
  324. }
  325. }
  326. }
  327. `;
  328. const GET_CALCULATORS = gql`
  329. query GetCalculators {
  330. shippingCalculators {
  331. code
  332. description
  333. args {
  334. name
  335. type
  336. description
  337. label
  338. ui
  339. }
  340. }
  341. }
  342. `;
  343. const TEST_SHIPPING_METHOD = gql`
  344. query TestShippingMethod($input: TestShippingMethodInput!) {
  345. testShippingMethod(input: $input) {
  346. eligible
  347. quote {
  348. price
  349. priceWithTax
  350. metadata
  351. }
  352. }
  353. }
  354. `;
  355. export const TEST_ELIGIBLE_SHIPPING_METHODS = gql`
  356. query TestEligibleMethods($input: TestEligibleShippingMethodsInput!) {
  357. testEligibleShippingMethods(input: $input) {
  358. id
  359. name
  360. description
  361. price
  362. priceWithTax
  363. metadata
  364. }
  365. }
  366. `;