order-taxes.e2e-spec.ts 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /* tslint:disable:no-non-null-assertion */
  2. import { createErrorResultGuard, createTestEnvironment, ErrorResultGuard } from '@vendure/testing';
  3. import gql from 'graphql-tag';
  4. import path from 'path';
  5. import { initialData } from '../../../e2e-common/e2e-initial-data';
  6. import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
  7. import { testSuccessfulPaymentMethod } from './fixtures/test-payment-methods';
  8. import { GetProductsWithVariantPrices, UpdateChannel } from './graphql/generated-e2e-admin-types';
  9. import {
  10. AddItemToOrder,
  11. AdjustmentType,
  12. GetActiveOrderWithPriceData,
  13. TestOrderFragmentFragment,
  14. UpdatedOrderFragment,
  15. } from './graphql/generated-e2e-shop-types';
  16. import { GET_PRODUCTS_WITH_VARIANT_PRICES, UPDATE_CHANNEL } from './graphql/shared-definitions';
  17. import { ADD_ITEM_TO_ORDER, GET_ACTIVE_ORDER_WITH_PRICE_DATA } from './graphql/shop-definitions';
  18. describe('Order taxes', () => {
  19. const { server, adminClient, shopClient } = createTestEnvironment({
  20. ...testConfig,
  21. paymentOptions: {
  22. paymentMethodHandlers: [testSuccessfulPaymentMethod],
  23. },
  24. });
  25. type OrderSuccessResult = UpdatedOrderFragment | TestOrderFragmentFragment;
  26. const orderResultGuard: ErrorResultGuard<OrderSuccessResult> = createErrorResultGuard<OrderSuccessResult>(
  27. input => !!input.lines,
  28. );
  29. let products: GetProductsWithVariantPrices.Items[];
  30. beforeAll(async () => {
  31. await server.init({
  32. initialData,
  33. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-order-taxes.csv'),
  34. customerCount: 2,
  35. });
  36. await adminClient.asSuperAdmin();
  37. const result = await adminClient.query<GetProductsWithVariantPrices.Query>(
  38. GET_PRODUCTS_WITH_VARIANT_PRICES,
  39. );
  40. products = result.products.items;
  41. }, TEST_SETUP_TIMEOUT_MS);
  42. afterAll(async () => {
  43. await server.destroy();
  44. });
  45. describe('Channel.pricesIncludeTax = false', () => {
  46. beforeAll(async () => {
  47. await adminClient.query<UpdateChannel.Mutation, UpdateChannel.Variables>(UPDATE_CHANNEL, {
  48. input: {
  49. id: 'T_1',
  50. pricesIncludeTax: false,
  51. },
  52. });
  53. await shopClient.asAnonymousUser();
  54. });
  55. it('prices are correct', async () => {
  56. const variant = products[0].variants[0];
  57. await shopClient.query<AddItemToOrder.Mutation, AddItemToOrder.Variables>(ADD_ITEM_TO_ORDER, {
  58. productVariantId: variant.id,
  59. quantity: 2,
  60. });
  61. const { activeOrder } = await shopClient.query<GetActiveOrderWithPriceData.Query>(
  62. GET_ACTIVE_ORDER_WITH_PRICE_DATA,
  63. );
  64. expect(activeOrder?.total).toBe(240);
  65. expect(activeOrder?.totalBeforeTax).toBe(200);
  66. expect(activeOrder?.lines[0].taxRate).toBe(20);
  67. expect(activeOrder?.lines[0].linePrice).toBe(200);
  68. expect(activeOrder?.lines[0].lineTax).toBe(40);
  69. expect(activeOrder?.lines[0].linePriceWithTax).toBe(240);
  70. expect(activeOrder?.lines[0].unitPrice).toBe(100);
  71. expect(activeOrder?.lines[0].unitPriceWithTax).toBe(120);
  72. expect(activeOrder?.lines[0].items[0].unitPrice).toBe(100);
  73. expect(activeOrder?.lines[0].items[0].unitPriceWithTax).toBe(120);
  74. expect(activeOrder?.lines[0].items[0].taxRate).toBe(20);
  75. expect(activeOrder?.lines[0].adjustments).toEqual([
  76. {
  77. type: AdjustmentType.TAX,
  78. amount: 20,
  79. },
  80. {
  81. type: AdjustmentType.TAX,
  82. amount: 20,
  83. },
  84. ]);
  85. });
  86. });
  87. describe('Channel.pricesIncludeTax = true', () => {
  88. beforeAll(async () => {
  89. await adminClient.query<UpdateChannel.Mutation, UpdateChannel.Variables>(UPDATE_CHANNEL, {
  90. input: {
  91. id: 'T_1',
  92. pricesIncludeTax: true,
  93. },
  94. });
  95. await shopClient.asAnonymousUser();
  96. });
  97. it('prices are correct', async () => {
  98. const variant = products[0].variants[0];
  99. await shopClient.query<AddItemToOrder.Mutation, AddItemToOrder.Variables>(ADD_ITEM_TO_ORDER, {
  100. productVariantId: variant.id,
  101. quantity: 2,
  102. });
  103. const { activeOrder } = await shopClient.query<GetActiveOrderWithPriceData.Query>(
  104. GET_ACTIVE_ORDER_WITH_PRICE_DATA,
  105. );
  106. expect(activeOrder?.total).toBe(200);
  107. expect(activeOrder?.totalBeforeTax).toBe(166);
  108. expect(activeOrder?.lines[0].taxRate).toBe(20);
  109. expect(activeOrder?.lines[0].linePrice).toBe(166);
  110. expect(activeOrder?.lines[0].lineTax).toBe(34);
  111. expect(activeOrder?.lines[0].linePriceWithTax).toBe(200);
  112. expect(activeOrder?.lines[0].unitPrice).toBe(83);
  113. expect(activeOrder?.lines[0].unitPriceWithTax).toBe(100);
  114. expect(activeOrder?.lines[0].items[0].unitPrice).toBe(83);
  115. expect(activeOrder?.lines[0].items[0].unitPriceWithTax).toBe(100);
  116. expect(activeOrder?.lines[0].items[0].taxRate).toBe(20);
  117. expect(activeOrder?.lines[0].adjustments).toEqual([
  118. {
  119. type: AdjustmentType.TAX,
  120. amount: 17,
  121. },
  122. {
  123. type: AdjustmentType.TAX,
  124. amount: 17,
  125. },
  126. ]);
  127. });
  128. });
  129. it('taxSummary works', async () => {
  130. await adminClient.query<UpdateChannel.Mutation, UpdateChannel.Variables>(UPDATE_CHANNEL, {
  131. input: {
  132. id: 'T_1',
  133. pricesIncludeTax: false,
  134. },
  135. });
  136. await shopClient.asAnonymousUser();
  137. await shopClient.query<AddItemToOrder.Mutation, AddItemToOrder.Variables>(ADD_ITEM_TO_ORDER, {
  138. productVariantId: products[0].variants[0].id,
  139. quantity: 2,
  140. });
  141. await shopClient.query<AddItemToOrder.Mutation, AddItemToOrder.Variables>(ADD_ITEM_TO_ORDER, {
  142. productVariantId: products[1].variants[0].id,
  143. quantity: 2,
  144. });
  145. await shopClient.query<AddItemToOrder.Mutation, AddItemToOrder.Variables>(ADD_ITEM_TO_ORDER, {
  146. productVariantId: products[2].variants[0].id,
  147. quantity: 2,
  148. });
  149. const { activeOrder } = await shopClient.query<GetActiveOrderWithPriceData.Query>(
  150. GET_ACTIVE_ORDER_WITH_PRICE_DATA,
  151. );
  152. expect(activeOrder?.taxSummary).toEqual([
  153. {
  154. taxRate: 20,
  155. taxBase: 200,
  156. taxTotal: 40,
  157. },
  158. {
  159. taxRate: 10,
  160. taxBase: 200,
  161. taxTotal: 20,
  162. },
  163. {
  164. taxRate: 0,
  165. taxBase: 200,
  166. taxTotal: 0,
  167. },
  168. ]);
  169. // ensure that the summary total add up to the overall totals
  170. const taxSummaryBaseTotal = activeOrder!.taxSummary.reduce((total, row) => total + row.taxBase, 0);
  171. const taxSummaryTaxTotal = activeOrder!.taxSummary.reduce((total, row) => total + row.taxTotal, 0);
  172. expect(taxSummaryBaseTotal).toBe(activeOrder?.totalBeforeTax);
  173. expect(taxSummaryBaseTotal + taxSummaryTaxTotal).toBe(activeOrder?.total);
  174. });
  175. });