@labdigital/commercetools-mock 1.9.0 → 1.11.0

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@labdigital/commercetools-mock",
3
3
  "author": "Michael van Tellingen",
4
- "version": "1.9.0",
4
+ "version": "1.11.0",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.js",
@@ -4,6 +4,8 @@ import type {
4
4
  Cart,
5
5
  CartAddLineItemAction,
6
6
  CartChangeLineItemQuantityAction,
7
+ CartAddItemShippingAddressAction,
8
+ CartSetLineItemShippingDetailsAction,
7
9
  CartDraft,
8
10
  CartRemoveLineItemAction,
9
11
  CartSetBillingAddressAction,
@@ -18,9 +20,11 @@ import type {
18
20
  GeneralError,
19
21
  LineItem,
20
22
  LineItemDraft,
23
+ ItemShippingDetails,
21
24
  Price,
22
25
  Product,
23
26
  ProductPagedQueryResponse,
27
+ CartRemoveDiscountCodeAction,
24
28
  ProductVariant,
25
29
  } from '@commercetools/platform-sdk'
26
30
  import { v4 as uuidv4 } from 'uuid'
@@ -215,6 +219,20 @@ export class CartRepository extends AbstractResourceRepository<'cart'> {
215
219
  // Update cart total price
216
220
  resource.totalPrice.centAmount = calculateCartTotalPrice(resource)
217
221
  },
222
+ addItemShippingAddress: (
223
+ context: RepositoryContext,
224
+ resource: Writable<Cart>,
225
+ { action, address }: CartAddItemShippingAddressAction
226
+ ) => {
227
+ const newAddress = createAddress(
228
+ address,
229
+ context.projectKey,
230
+ this._storage
231
+ )
232
+ if (newAddress) {
233
+ resource.itemShippingAddresses.push(newAddress)
234
+ }
235
+ },
218
236
  changeLineItemQuantity: (
219
237
  context: RepositoryContext,
220
238
  resource: Writable<Cart>,
@@ -391,6 +409,37 @@ export class CartRepository extends AbstractResourceRepository<'cart'> {
391
409
  ) => {
392
410
  resource.locale = locale
393
411
  },
412
+ setLineItemShippingDetails: (
413
+ context: RepositoryContext,
414
+ resource: Writable<Cart>,
415
+ {
416
+ action,
417
+ shippingDetails,
418
+ lineItemId,
419
+ lineItemKey,
420
+ }: CartSetLineItemShippingDetailsAction
421
+ ) => {
422
+ const lineItem = resource.lineItems.find(
423
+ (x) =>
424
+ (lineItemId && x.id === lineItemId) ||
425
+ (lineItemKey && x.key === lineItemKey)
426
+ )
427
+
428
+ if (!lineItem) {
429
+ // Check if line item is found
430
+ throw new CommercetoolsError<GeneralError>({
431
+ code: 'General',
432
+ message: lineItemKey
433
+ ? `A line item with key '${lineItemKey}' not found.`
434
+ : `A line item with ID '${lineItemId}' not found.`,
435
+ })
436
+ }
437
+
438
+ lineItem.shippingDetails = {
439
+ ...shippingDetails,
440
+ valid: true,
441
+ } as ItemShippingDetails
442
+ },
394
443
  setShippingAddress: (
395
444
  context: RepositoryContext,
396
445
  resource: Writable<Cart>,
@@ -415,6 +464,15 @@ export class CartRepository extends AbstractResourceRepository<'cart'> {
415
464
  custom: custom,
416
465
  }
417
466
  },
467
+ removeDiscountCode: (
468
+ context: RepositoryContext,
469
+ resource: Writable<Cart>,
470
+ { discountCode }: CartRemoveDiscountCodeAction
471
+ ) => {
472
+ resource.discountCodes = resource.discountCodes.filter(
473
+ (code) => code.discountCode.id !== discountCode.id
474
+ )
475
+ },
418
476
  }
419
477
  draftLineItemtoLineItem = (
420
478
  projectKey: string,
@@ -1,8 +1,8 @@
1
1
  import type {
2
2
  ProductSelection,
3
+ ProductSelectionChangeNameAction,
3
4
  ProductSelectionDraft,
4
- Review,
5
- ReviewUpdateAction,
5
+ ProductSelectionUpdateAction,
6
6
  } from '@commercetools/platform-sdk'
7
7
  import { getBaseResourceProperties } from '../helpers.js'
8
8
  import type { Writable } from '../types.js'
@@ -20,6 +20,7 @@ export class ProductSelectionRepository extends AbstractResourceRepository<'prod
20
20
  const resource: ProductSelection = {
21
21
  ...getBaseResourceProperties(),
22
22
  productCount: 0,
23
+ key: draft.key,
23
24
  name: draft.name,
24
25
  type: 'individual',
25
26
  mode: 'Individual',
@@ -30,12 +31,20 @@ export class ProductSelectionRepository extends AbstractResourceRepository<'prod
30
31
 
31
32
  actions: Partial<
32
33
  Record<
33
- ReviewUpdateAction['action'],
34
+ ProductSelectionUpdateAction['action'],
34
35
  (
35
36
  context: RepositoryContext,
36
- resource: Writable<Review>,
37
+ resource: Writable<ProductSelection>,
37
38
  action: any
38
39
  ) => void
39
40
  >
40
- > = {}
41
+ > = {
42
+ changeName: (
43
+ context: RepositoryContext,
44
+ resource: Writable<ProductSelection>,
45
+ { name }: ProductSelectionChangeNameAction
46
+ ) => {
47
+ resource.name = name
48
+ },
49
+ }
41
50
  }
@@ -35,7 +35,7 @@ describe('Associate roles query', () => {
35
35
  expect(response.status).toBe(200)
36
36
  expect(response.body.count).toBe(1)
37
37
 
38
- const associateRole = response.body.results[0] as AssociateRole
38
+ associateRole = response.body.results[0] as AssociateRole
39
39
 
40
40
  expect(associateRole.key).toBe('example-role-associate-role')
41
41
  })
@@ -35,7 +35,7 @@ describe('Business units query', () => {
35
35
  expect(response.status).toBe(200)
36
36
  expect(response.body.count).toBe(1)
37
37
 
38
- const businessUnit = response.body.results[0] as BusinessUnit
38
+ businessUnit = response.body.results[0] as BusinessUnit
39
39
 
40
40
  expect(businessUnit.key).toBe('example-business-unit')
41
41
  })
@@ -272,6 +272,37 @@ describe('Cart Update Actions', () => {
272
272
  expect(response.body.message).toBe("A product with ID '123' not found.")
273
273
  })
274
274
 
275
+ test('addItemShippingAddress', async () => {
276
+ const product = await supertest(ctMock.app)
277
+ .post(`/dummy/products`)
278
+ .send(productDraft)
279
+ .then((x) => x.body)
280
+
281
+ assert(cart, 'cart not created')
282
+
283
+ const response = await supertest(ctMock.app)
284
+ .post(`/dummy/carts/${cart.id}`)
285
+ .send({
286
+ version: 1,
287
+ actions: [
288
+ {
289
+ action: 'addItemShippingAddress',
290
+ address: {
291
+ firstName: 'John',
292
+ lastName: 'Doe',
293
+ company: 'My Company',
294
+ country: 'NL',
295
+ },
296
+ },
297
+ ],
298
+ })
299
+
300
+ expect(response.body.itemShippingAddresses).toHaveLength(1)
301
+ expect(response.status).toBe(200)
302
+ expect(response.body.version).toBe(2)
303
+ expect(response.body.lineItems).toHaveLength(0)
304
+ })
305
+
275
306
  test('removeLineItem', async () => {
276
307
  const product = await supertest(ctMock.app)
277
308
  .post(`/dummy/products`)
@@ -418,4 +449,60 @@ describe('Cart Update Actions', () => {
418
449
  expect(response.body.version).toBe(2)
419
450
  expect(response.body.shippingAddress).toEqual(address)
420
451
  })
452
+
453
+ test('setLineItemShippingDetails', async () => {
454
+ const product = await supertest(ctMock.app)
455
+ .post(`/dummy/products`)
456
+ .send(productDraft)
457
+ .then((x) => x.body)
458
+
459
+ assert(cart, 'cart not created')
460
+ assert(product, 'product not created')
461
+
462
+ const updatedCart = await supertest(ctMock.app)
463
+ .post(`/dummy/carts/${cart.id}`)
464
+ .send({
465
+ version: 1,
466
+ actions: [
467
+ {
468
+ action: 'addLineItem',
469
+ productId: product.id,
470
+ variantId: product.masterData.current.variants[0].id,
471
+ },
472
+ ],
473
+ })
474
+ const lineItem = updatedCart.body.lineItems[0]
475
+ assert(lineItem, 'lineItem not created')
476
+
477
+ expect(updatedCart.body.version).toBe(2)
478
+ expect(updatedCart.body.lineItems).toHaveLength(1)
479
+
480
+ const response = await supertest(ctMock.app)
481
+ .post(`/dummy/carts/${cart.id}`)
482
+ .send({
483
+ version: updatedCart.body.version,
484
+ actions: [
485
+ {
486
+ action: 'setLineItemShippingDetails',
487
+ lineItemId: lineItem.id,
488
+ shippingDetails: {
489
+ targets: [
490
+ {
491
+ addressKey: 'address-key',
492
+ quantity: 1,
493
+ },
494
+ ],
495
+ },
496
+ },
497
+ ],
498
+ })
499
+
500
+ expect(response.status).toBe(200)
501
+ expect(response.body.version).toBe(3)
502
+ expect(response.body.lineItems).toHaveLength(1)
503
+
504
+ const updatedLineItem = response.body.lineItems[0]
505
+ expect(updatedLineItem.shippingDetails).toBeDefined()
506
+ expect(updatedLineItem.shippingDetails.targets).toHaveLength(1)
507
+ })
421
508
  })
@@ -42,7 +42,7 @@ describe('Categories Query', () => {
42
42
  expect(response.status).toBe(200)
43
43
  expect(response.body.count).toBe(1)
44
44
 
45
- const category = response.body.results[0] as Category
45
+ category = response.body.results[0] as Category
46
46
 
47
47
  expect(category.name.en).toBe('Top hat')
48
48
  })
@@ -27,6 +27,7 @@ export class CustomerService extends AbstractService {
27
27
  ? // @ts-ignore
28
28
  +request.params.ttlMinutes
29
29
  : 34560
30
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
30
31
  const { version, ...rest } = getBaseResourceProperties()
31
32
 
32
33
  return response.status(200).send({
@@ -1,12 +1,13 @@
1
1
  import { AssociateRoleServices } from './associate-roles.js'
2
+ import { AttributeGroupService } from './attribute-group.js'
2
3
  import { BusinessUnitServices } from './business-units.js'
3
- import { CartService } from './cart.js'
4
4
  import { CartDiscountService } from './cart-discount.js'
5
+ import { CartService } from './cart.js'
5
6
  import { CategoryServices } from './category.js'
6
7
  import { ChannelService } from './channel.js'
7
8
  import { CustomObjectService } from './custom-object.js'
8
- import { CustomerService } from './customer.js'
9
9
  import { CustomerGroupService } from './customer-group.js'
10
+ import { CustomerService } from './customer.js'
10
11
  import { DiscountCodeService } from './discount-code.js'
11
12
  import { ExtensionServices } from './extension.js'
12
13
  import { InventoryEntryService } from './inventory-entry.js'
@@ -16,10 +17,11 @@ import { MyOrderService } from './my-order.js'
16
17
  import { MyPaymentService } from './my-payment.js'
17
18
  import { OrderService } from './order.js'
18
19
  import { PaymentService } from './payment.js'
19
- import { ProductService } from './product.js'
20
20
  import { ProductDiscountService } from './product-discount.js'
21
21
  import { ProductProjectionService } from './product-projection.js'
22
+ import { ProductSelectionService } from './product-selection.js'
22
23
  import { ProductTypeService } from './product-type.js'
24
+ import { ProductService } from './product.js'
23
25
  import { ShippingMethodService } from './shipping-method.js'
24
26
  import { ShoppingListService } from './shopping-list.js'
25
27
  import { StandAlonePriceService } from './standalone-price.js'
@@ -29,7 +31,6 @@ import { SubscriptionService } from './subscription.js'
29
31
  import { TaxCategoryService } from './tax-category.js'
30
32
  import { TypeService } from './type.js'
31
33
  import { ZoneService } from './zone.js'
32
- import { AttributeGroupService } from './attribute-group.js'
33
34
 
34
35
  export const createServices = (router: any, repos: any) => ({
35
36
  'associate-role': new AssociateRoleServices(router, repos['associate-role']),
@@ -74,6 +75,10 @@ export const createServices = (router: any, repos: any) => ({
74
75
  router,
75
76
  repos['product-projection']
76
77
  ),
78
+ 'product-selection': new ProductSelectionService(
79
+ router,
80
+ repos['product-selection']
81
+ ),
77
82
  'shopping-list': new ShoppingListService(router, repos['shopping-list']),
78
83
  state: new StateService(router, repos['state']),
79
84
  store: new StoreService(router, repos['store']),
@@ -0,0 +1,36 @@
1
+ import type { ProductSelectionDraft } from '@commercetools/platform-sdk'
2
+ import supertest from 'supertest'
3
+ import { describe, expect, test } from 'vitest'
4
+ import { CommercetoolsMock } from '../index.js'
5
+
6
+ const ctMock = new CommercetoolsMock()
7
+
8
+ describe('product-selection', () => {
9
+ test('Create product selection', async () => {
10
+ const draft: ProductSelectionDraft = {
11
+ name: {
12
+ en: 'foo',
13
+ },
14
+ key: 'foo',
15
+ }
16
+ const response = await supertest(ctMock.app)
17
+ .post('/dummy/product-selections')
18
+ .send(draft)
19
+
20
+ expect(response.status).toBe(201)
21
+
22
+ expect(response.body).toEqual({
23
+ createdAt: expect.anything(),
24
+ id: expect.anything(),
25
+ lastModifiedAt: expect.anything(),
26
+ name: {
27
+ en: 'foo',
28
+ },
29
+ key: 'foo',
30
+ version: 1,
31
+ productCount: 0,
32
+ type: 'individual',
33
+ mode: 'Individual',
34
+ })
35
+ })
36
+ })
@@ -0,0 +1,16 @@
1
+ import { Router } from 'express'
2
+ import AbstractService from './abstract.js'
3
+ import { ProductSelectionRepository } from '../repositories/product-selection.js'
4
+
5
+ export class ProductSelectionService extends AbstractService {
6
+ public repository: ProductSelectionRepository
7
+
8
+ constructor(parent: Router, repository: ProductSelectionRepository) {
9
+ super(parent)
10
+ this.repository = repository
11
+ }
12
+
13
+ getBasePath() {
14
+ return 'product-selections'
15
+ }
16
+ }
@@ -163,7 +163,6 @@ describe('Product', () => {
163
163
  describe('Product update actions', () => {
164
164
  const ctMock = new CommercetoolsMock()
165
165
  let productPublished: Product | undefined
166
- let productUnpublished: Product | undefined
167
166
 
168
167
  beforeEach(async () => {
169
168
  let response
@@ -179,7 +178,6 @@ describe('Product update actions', () => {
179
178
  .send(unpublishedProductDraft)
180
179
 
181
180
  expect(response.status).toBe(201)
182
- productUnpublished = response.body
183
181
  })
184
182
 
185
183
  test('setAttribute masterVariant (staged)', async () => {