@labdigital/commercetools-mock 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,5 +17,5 @@ export declare class CartRepository extends AbstractResourceRepository {
17
17
  setLocale: (projectKey: string, resource: Writable<Cart>, { locale }: CartSetLocaleAction) => void;
18
18
  setShippingAddress: (projectKey: string, resource: Writable<Cart>, { address }: CartSetShippingAddressAction) => void;
19
19
  };
20
- draftLineItemtoLineItem: (projectKey: string, draftLineItem: LineItemDraft) => LineItem;
20
+ draftLineItemtoLineItem: (projectKey: string, draftLineItem: LineItemDraft, currency: string, country: string | undefined) => LineItem;
21
21
  }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.6.0",
2
+ "version": "0.6.1",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -14,6 +14,7 @@ import {
14
14
  GeneralError,
15
15
  LineItem,
16
16
  LineItemDraft,
17
+ Price,
17
18
  Product,
18
19
  ProductPagedQueryResponse,
19
20
  ProductVariant,
@@ -32,14 +33,20 @@ export class CartRepository extends AbstractResourceRepository {
32
33
  }
33
34
 
34
35
  create(projectKey: string, draft: CartDraft): Cart {
35
- const lineItems = draft.lineItems?.map(draftLineItem =>
36
- this.draftLineItemtoLineItem(projectKey, draftLineItem)
37
- )
36
+ const lineItems =
37
+ draft.lineItems?.map(draftLineItem =>
38
+ this.draftLineItemtoLineItem(
39
+ projectKey,
40
+ draftLineItem,
41
+ draft.currency,
42
+ draft.country
43
+ )
44
+ ) ?? []
38
45
 
39
46
  const resource: Cart = {
40
47
  ...getBaseResourceProperties(),
41
48
  cartState: 'Active',
42
- lineItems: lineItems ?? [],
49
+ lineItems,
43
50
  customLineItems: [],
44
51
  totalPrice: {
45
52
  type: 'centPrecision',
@@ -47,11 +54,13 @@ export class CartRepository extends AbstractResourceRepository {
47
54
  currencyCode: draft.currency,
48
55
  fractionDigits: 0,
49
56
  },
50
- taxMode: 'Platform',
51
- taxRoundingMode: 'HalfEven',
52
- taxCalculationMode: 'LineItemLevel',
57
+ taxMode: draft.taxMode ?? 'Platform',
58
+ taxRoundingMode: draft.taxRoundingMode ?? 'HalfEven',
59
+ taxCalculationMode: draft.taxCalculationMode ?? 'LineItemLevel',
53
60
  refusedGifts: [],
54
- origin: 'Customer',
61
+ locale: draft.locale,
62
+ country: draft.country,
63
+ origin: draft.origin ?? 'Customer',
55
64
  custom: createCustomFields(draft.custom, projectKey, this._storage),
56
65
  }
57
66
 
@@ -150,7 +159,18 @@ export class CartRepository extends AbstractResourceRepository {
150
159
  })
151
160
  }
152
161
 
153
- const price = variant.prices[0]
162
+ const currency = resource.totalPrice.currencyCode
163
+
164
+ const price = selectPrice({
165
+ prices: variant.prices,
166
+ currency,
167
+ country: resource.country,
168
+ })
169
+ if (!price) {
170
+ throw new Error(
171
+ `No valid price found for ${productId} for country ${resource.country} and currency ${currency}`
172
+ )
173
+ }
154
174
  resource.lineItems.push({
155
175
  id: uuidv4(),
156
176
  productId: product.id,
@@ -302,13 +322,12 @@ export class CartRepository extends AbstractResourceRepository {
302
322
  }
303
323
  draftLineItemtoLineItem = (
304
324
  projectKey: string,
305
- draftLineItem: LineItemDraft
325
+ draftLineItem: LineItemDraft,
326
+ currency: string,
327
+ country: string | undefined
306
328
  ): LineItem => {
307
- const { productId, quantity } = draftLineItem
308
- // @ts-ignore
309
- let variantId = draftLineItem.variant.id
310
- // @ts-ignore
311
- let sku = draftLineItem.variant.sku
329
+ const { productId, quantity, variantId, sku } = draftLineItem
330
+
312
331
  let product: Product | null = null
313
332
  let variant: ProductVariant | undefined
314
333
 
@@ -357,12 +376,13 @@ export class CartRepository extends AbstractResourceRepository {
357
376
  )
358
377
  }
359
378
 
360
- const price = variant.prices?.[0]
361
-
362
379
  const quant = quantity ?? 1
363
380
 
381
+ const price = selectPrice({ prices: variant.prices, currency, country })
364
382
  if (!price) {
365
- throw new Error(`Price not set on ${productId}`)
383
+ throw new Error(
384
+ `No valid price found for ${productId} for country ${country} and currency ${currency}`
385
+ )
366
386
  }
367
387
 
368
388
  return {
@@ -387,6 +407,29 @@ export class CartRepository extends AbstractResourceRepository {
387
407
  }
388
408
  }
389
409
 
410
+ const selectPrice = ({
411
+ prices,
412
+ currency,
413
+ country,
414
+ }: {
415
+ prices: Price[] | undefined
416
+ currency: string
417
+ country: string | undefined
418
+ }) => {
419
+ if (!prices) {
420
+ return undefined
421
+ }
422
+
423
+ // Quick-and-dirty way of selecting price based on the given currency and country.
424
+ // Can be improved later to give more priority to exact matches over
425
+ // 'all country' matches, and include customer groups in the mix as well
426
+ return prices.find(price => {
427
+ const countryMatch = !price.country || price.country === country
428
+ const currencyMatch = price.value.currencyCode === currency
429
+ return countryMatch && currencyMatch
430
+ })
431
+ }
432
+
390
433
  const calculateLineItemTotalPrice = (lineItem: LineItem): number =>
391
434
  lineItem.price!.value.centAmount * lineItem.quantity
392
435
 
@@ -76,9 +76,20 @@ describe('Carts Query', () => {
76
76
  })
77
77
  })
78
78
 
79
- describe('Order Update Actions', () => {
79
+ describe('Cart Update Actions', () => {
80
80
  const ctMock = new CommercetoolsMock()
81
81
  let cart: Cart | undefined
82
+
83
+ const createCart = async (currency: string) => {
84
+ let response = await supertest(ctMock.app)
85
+ .post('/dummy/carts')
86
+ .send({
87
+ currency,
88
+ })
89
+ expect(response.status).toBe(201)
90
+ cart = response.body
91
+ }
92
+
82
93
  const productDraft: ProductDraft = {
83
94
  name: {
84
95
  'nl-NL': 'test product',
@@ -98,6 +109,14 @@ describe('Order Update Actions', () => {
98
109
  fractionDigits: 2,
99
110
  } as CentPrecisionMoney,
100
111
  },
112
+ {
113
+ value: {
114
+ type: 'centPrecision',
115
+ currencyCode: 'GBP',
116
+ centAmount: 18900,
117
+ fractionDigits: 2,
118
+ } as CentPrecisionMoney,
119
+ },
101
120
  ],
102
121
 
103
122
  attributes: [
@@ -135,13 +154,7 @@ describe('Order Update Actions', () => {
135
154
  }
136
155
 
137
156
  beforeEach(async () => {
138
- let response = await supertest(ctMock.app)
139
- .post('/dummy/carts')
140
- .send({
141
- currency: 'EUR',
142
- })
143
- expect(response.status).toBe(201)
144
- cart = response.body
157
+ await createCart('EUR')
145
158
  })
146
159
 
147
160
  afterEach(() => {
@@ -220,6 +233,33 @@ describe('Order Update Actions', () => {
220
233
  expect(response.body.totalPrice.centAmount).toEqual(29800)
221
234
  })
222
235
 
236
+ test.each([
237
+ ['EUR', 29800],
238
+ ['GBP', 37800],
239
+ ])('addLineItem with price selection', async (currency, total) => {
240
+ await createCart(currency)
241
+
242
+ const product = await supertest(ctMock.app)
243
+ .post(`/dummy/products`)
244
+ .send(productDraft)
245
+ .then(x => x.body)
246
+
247
+ assert(cart, 'cart not created')
248
+ assert(product, 'product not created')
249
+
250
+ const response = await supertest(ctMock.app)
251
+ .post(`/dummy/carts/${cart.id}`)
252
+ .send({
253
+ version: 1,
254
+ actions: [{ action: 'addLineItem', sku: '1337', quantity: 2 }],
255
+ })
256
+ expect(response.status).toBe(200)
257
+ expect(response.body.version).toBe(2)
258
+ expect(response.body.lineItems).toHaveLength(1)
259
+ expect(response.body.lineItems[0].price.value.currencyCode).toBe(currency)
260
+ expect(response.body.totalPrice.centAmount).toEqual(total)
261
+ })
262
+
223
263
  test('addLineItem unknown product', async () => {
224
264
  assert(cart, 'cart not created')
225
265
 
@@ -2,7 +2,7 @@ import AbstractService from './abstract'
2
2
  import { Router } from 'express'
3
3
  import { CartRepository } from '../repositories/cart'
4
4
  import { AbstractStorage } from '../storage'
5
- import { Cart, Order } from '@commercetools/platform-sdk'
5
+ import { Cart, CartDraft, Order } from '@commercetools/platform-sdk'
6
6
  import { OrderRepository } from '../repositories/order'
7
7
 
8
8
  export class CartService extends AbstractService {
@@ -37,11 +37,23 @@ export class CartService extends AbstractService {
37
37
  return response.status(400).send()
38
38
  }
39
39
 
40
- const newCart = this.repository.create(request.params.projectKey, {
40
+ const cartDraft: CartDraft = {
41
41
  ...cartOrOrder,
42
42
  currency: cartOrOrder.totalPrice.currencyCode,
43
43
  discountCodes: [],
44
- })
44
+ lineItems: cartOrOrder.lineItems.map(lineItem => {
45
+ return {
46
+ ...lineItem,
47
+ variantId: lineItem.variant.id,
48
+ sku: lineItem.variant.sku,
49
+ }
50
+ }),
51
+ }
52
+
53
+ const newCart = this.repository.create(
54
+ request.params.projectKey,
55
+ cartDraft
56
+ )
45
57
 
46
58
  return response.status(200).send(newCart)
47
59
  })