@labdigital/commercetools-mock 2.56.0 → 2.57.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,6 +1,6 @@
1
1
  {
2
2
  "name": "@labdigital/commercetools-mock",
3
- "version": "2.56.0",
3
+ "version": "2.57.0",
4
4
  "license": "MIT",
5
5
  "author": "Michael van Tellingen",
6
6
  "type": "module",
@@ -31,7 +31,7 @@
31
31
  "@types/express": "^5.0.1",
32
32
  "@changesets/changelog-github": "0.5.1",
33
33
  "@changesets/cli": "2.28.1",
34
- "@commercetools/platform-sdk": "8.14.0",
34
+ "@commercetools/platform-sdk": "8.16.0",
35
35
  "@types/basic-auth": "1.1.8",
36
36
  "@types/body-parser": "1.19.5",
37
37
  "@types/express-serve-static-core": "^5.0.6",
@@ -346,7 +346,7 @@ export class CartUpdateHandler
346
346
  context.projectKey,
347
347
  { money, name, slug, quantity, taxCategory, custom, priceMode, key },
348
348
  this._storage,
349
- resource.country,
349
+ resource.shippingAddress?.country ?? resource.country,
350
350
  );
351
351
 
352
352
  resource.customLineItems.push(customLineItem);
@@ -150,7 +150,6 @@ export const createCustomLineItemFromDraft = (
150
150
  )
151
151
  : undefined;
152
152
 
153
- // Get the tax category to calculate taxed price
154
153
  let taxCategory: TaxCategory | undefined = undefined;
155
154
  if (taxCategoryRef) {
156
155
  try {
@@ -167,7 +166,6 @@ export const createCustomLineItemFromDraft = (
167
166
  centAmount: (draft.money.centAmount ?? 0) * quantity,
168
167
  });
169
168
 
170
- // Calculate taxed price if tax category is available
171
169
  const taxedPrice = taxCategory
172
170
  ? calculateTaxedPrice(
173
171
  totalPrice.centAmount,
@@ -177,6 +175,12 @@ export const createCustomLineItemFromDraft = (
177
175
  )
178
176
  : undefined;
179
177
 
178
+ const taxRate = taxCategory
179
+ ? taxCategory.rates.find(
180
+ (rate) => !rate.country || rate.country === country,
181
+ )
182
+ : undefined;
183
+
180
184
  return {
181
185
  id: uuidv4(),
182
186
  key: draft.key,
@@ -186,6 +190,7 @@ export const createCustomLineItemFromDraft = (
186
190
  quantity: draft.quantity ?? 1,
187
191
  state: [],
188
192
  taxCategory: taxCategoryRef,
193
+ taxRate,
189
194
  taxedPrice,
190
195
  custom: createCustomFields(draft.custom, projectKey, storage),
191
196
  discountedPricePerQuantity: [],
@@ -293,5 +293,10 @@ describe("Cart repository", () => {
293
293
  expect(customLineItem.taxedPrice?.totalTax?.centAmount).toBe(210);
294
294
  expect(customLineItem.taxedPrice?.taxPortions).toHaveLength(1);
295
295
  expect(customLineItem.taxedPrice?.taxPortions[0].rate).toBe(0.21);
296
+ expect(customLineItem.taxRate).toBeDefined();
297
+ expect(customLineItem.taxRate?.amount).toBe(0.21);
298
+ expect(customLineItem.taxRate?.name).toBe("Standard VAT");
299
+ expect(customLineItem.taxRate?.includedInPrice).toBe(false);
300
+ expect(customLineItem.taxRate?.country).toBe("NL");
296
301
  });
297
302
  });
@@ -81,7 +81,7 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
81
81
  context.projectKey,
82
82
  draftCustomLineItem,
83
83
  this._storage,
84
- draft.country,
84
+ draft.shippingAddress?.country ?? draft.country,
85
85
  ),
86
86
  ) ?? [];
87
87
 
@@ -23,6 +23,7 @@ export class DiscountGroupRepository extends AbstractResourceRepository<"discoun
23
23
  name: draft.name,
24
24
  key: draft.key,
25
25
  sortOrder: draft.sortOrder,
26
+ isActive: true,
26
27
  };
27
28
  return this.saveNew(context, resource);
28
29
  }
@@ -1,5 +1,6 @@
1
1
  import type {
2
2
  Project,
3
+ ProjectChangeBusinessUnitSearchStatusAction,
3
4
  ProjectChangeBusinessUnitStatusOnCreationAction,
4
5
  ProjectChangeCartsConfigurationAction,
5
6
  ProjectChangeCountriesAction,
@@ -10,7 +11,10 @@ import type {
10
11
  ProjectChangeMessagesConfigurationAction,
11
12
  ProjectChangeNameAction,
12
13
  ProjectChangeOrderSearchStatusAction,
14
+ ProjectChangePriceRoundingModeAction,
13
15
  ProjectChangeProductSearchIndexingEnabledAction,
16
+ ProjectChangeShoppingListsConfigurationAction,
17
+ ProjectChangeTaxRoundingModeAction,
14
18
  ProjectSetExternalOAuthAction,
15
19
  ProjectSetShippingRateInputTypeAction,
16
20
  ProjectUpdateAction,
@@ -62,6 +66,20 @@ class ProjectUpdateHandler
62
66
  resource.carts = cartsConfiguration || {
63
67
  countryTaxRateFallbackEnabled: false,
64
68
  deleteDaysAfterLastModification: 90,
69
+ priceRoundingMode: "HalfEven",
70
+ taxRoundingMode: "HalfEven",
71
+ };
72
+ }
73
+
74
+ changeShoppingListsConfiguration(
75
+ context: RepositoryContext,
76
+ resource: Writable<Project>,
77
+ {
78
+ shoppingListsConfiguration,
79
+ }: ProjectChangeShoppingListsConfigurationAction,
80
+ ) {
81
+ resource.shoppingLists = shoppingListsConfiguration || {
82
+ deleteDaysAfterLastModification: 90,
65
83
  };
66
84
  }
67
85
 
@@ -84,6 +102,22 @@ class ProjectUpdateHandler
84
102
  countryTaxRateFallbackEnabled;
85
103
  }
86
104
 
105
+ changePriceRoundingMode(
106
+ context: RepositoryContext,
107
+ resource: Writable<Project>,
108
+ { priceRoundingMode }: ProjectChangePriceRoundingModeAction,
109
+ ) {
110
+ resource.carts.priceRoundingMode = priceRoundingMode;
111
+ }
112
+
113
+ changeTaxRoundingMode(
114
+ context: RepositoryContext,
115
+ resource: Writable<Project>,
116
+ { taxRoundingMode }: ProjectChangeTaxRoundingModeAction,
117
+ ) {
118
+ resource.carts.taxRoundingMode = taxRoundingMode;
119
+ }
120
+
87
121
  changeCurrencies(
88
122
  context: RepositoryContext,
89
123
  resource: Writable<Project>,
@@ -104,6 +138,19 @@ class ProjectUpdateHandler
104
138
  resource.searchIndexing.customers.lastModifiedAt = new Date().toISOString();
105
139
  }
106
140
 
141
+ changeBusinessUnitSearchStatus(
142
+ context: RepositoryContext,
143
+ resource: Writable<Project>,
144
+ { status }: ProjectChangeBusinessUnitSearchStatusAction,
145
+ ) {
146
+ if (!resource.searchIndexing?.businessUnits) {
147
+ throw new Error("Invalid project state");
148
+ }
149
+ resource.searchIndexing.businessUnits.status = status;
150
+ resource.searchIndexing.businessUnits.lastModifiedAt =
151
+ new Date().toISOString();
152
+ }
153
+
107
154
  changeLanguages(
108
155
  context: RepositoryContext,
109
156
  resource: Writable<Project>,
@@ -116,6 +116,7 @@ describe("Cart Update Actions", () => {
116
116
  const createCart = async (currency: string) => {
117
117
  const response = await supertest(ctMock.app).post("/dummy/carts").send({
118
118
  currency,
119
+ country: "NL",
119
120
  });
120
121
  expect(response.status).toBe(201);
121
122
  cart = response.body;
@@ -653,11 +654,11 @@ describe("Cart Update Actions", () => {
653
654
  .post(`/dummy/carts/${cart.id}`)
654
655
  .send({
655
656
  version: 1,
656
- actions: [{ action: "setCountry", country: "NL" }],
657
+ actions: [{ action: "setCountry", country: "BE" }],
657
658
  });
658
659
  expect(response.status).toBe(200);
659
660
  expect(response.body.version).toBe(2);
660
- expect(response.body.country).toBe("NL");
661
+ expect(response.body.country).toBe("BE");
661
662
  });
662
663
 
663
664
  test("setDirectDiscounts", async () => {
@@ -1399,6 +1400,8 @@ describe("Cart Update Actions", () => {
1399
1400
  expect(customLineItem.totalPrice.centAmount).toBe(1000);
1400
1401
  expect(customLineItem.taxCategory.id).toBe(taxCategory.id);
1401
1402
  expect(customLineItem.taxedPrice).toBeDefined();
1403
+ expect(customLineItem.taxRate).toBeDefined();
1404
+ expect(customLineItem.taxRate.amount).toBe(0.21);
1402
1405
  expect(customLineItem.id).toBeDefined();
1403
1406
  expect(customLineItem.custom).toBeDefined();
1404
1407
  expect(customLineItem.custom.fields.description).toBe(
@@ -27,6 +27,7 @@ describe("DiscountGroup", () => {
27
27
  createdAt: expect.anything(),
28
28
  id: expect.anything(),
29
29
  key: "premium-discount-group",
30
+ isActive: true,
30
31
  lastModifiedAt: expect.anything(),
31
32
  name: {
32
33
  "en-GB": "Premium Discount Group",
@@ -1,11 +1,15 @@
1
1
  import type { BusinessUnitDraft } from "@commercetools/platform-sdk";
2
2
  import supertest from "supertest";
3
- import { describe, expect, test } from "vitest";
3
+ import { afterEach, describe, expect, test } from "vitest";
4
4
  import { CommercetoolsMock } from "../index";
5
5
 
6
6
  const ctMock = new CommercetoolsMock();
7
7
 
8
8
  describe("MyBusinessUnit", () => {
9
+ afterEach(() => {
10
+ ctMock.clear();
11
+ });
12
+
9
13
  test("Get my business units", async () => {
10
14
  // First create a business unit
11
15
  const draft: BusinessUnitDraft = {
@@ -51,6 +55,28 @@ describe("MyBusinessUnit", () => {
51
55
  expect(response.body).toEqual(createResponse.body);
52
56
  });
53
57
 
58
+ test("Get my business unit by key", async () => {
59
+ // First create a business unit
60
+ const draft: BusinessUnitDraft = {
61
+ key: "my-business-unit",
62
+ unitType: "Company",
63
+ name: "My Business Unit",
64
+ contactEmail: "contact@example.com",
65
+ };
66
+ const createResponse = await supertest(ctMock.app)
67
+ .post("/dummy/business-units")
68
+ .send(draft);
69
+
70
+ expect(createResponse.status).toBe(201);
71
+
72
+ const response = await supertest(ctMock.app).get(
73
+ `/dummy/me/business-units/key=${createResponse.body.key}`,
74
+ );
75
+
76
+ expect(response.status).toBe(200);
77
+ expect(response.body).toEqual(createResponse.body);
78
+ });
79
+
54
80
  test("Delete my business unit", async () => {
55
81
  // First create a business unit
56
82
  const draft: BusinessUnitDraft = {
@@ -80,6 +106,35 @@ describe("MyBusinessUnit", () => {
80
106
  expect(newResponse.status).toBe(404);
81
107
  });
82
108
 
109
+ test("Delete my business unit by key", async () => {
110
+ // First create a business unit
111
+ const draft: BusinessUnitDraft = {
112
+ key: "my-business-unit",
113
+ unitType: "Company",
114
+ name: "My Business Unit",
115
+ contactEmail: "contact@example.com",
116
+ };
117
+ const createResponse = await supertest(ctMock.app)
118
+ .post("/dummy/business-units")
119
+ .send(draft);
120
+
121
+ expect(createResponse.status).toBe(201);
122
+
123
+ // Now delete the business unit
124
+ const deleteResponse = await supertest(ctMock.app).delete(
125
+ `/dummy/me/business-units/key=${createResponse.body.key}`,
126
+ );
127
+
128
+ expect(deleteResponse.status).toBe(200);
129
+ expect(deleteResponse.body).toEqual(createResponse.body);
130
+
131
+ // Verify that the business unit is deleted
132
+ const newResponse = await supertest(ctMock.app).get(
133
+ `/dummy/me/business-units/key=${createResponse.body.key}`,
134
+ );
135
+ expect(newResponse.status).toBe(404);
136
+ });
137
+
83
138
  test("Update my business unit", async () => {
84
139
  // First create a business unit
85
140
  const draft: BusinessUnitDraft = {
@@ -110,4 +165,35 @@ describe("MyBusinessUnit", () => {
110
165
  expect(updateResponse.status).toBe(200);
111
166
  expect(updateResponse.body.name).toBe("Updated Business Unit Name");
112
167
  });
168
+
169
+ test("Update my business unit by key", async () => {
170
+ // First create a business unit
171
+ const draft: BusinessUnitDraft = {
172
+ key: "my-business-unit",
173
+ unitType: "Company",
174
+ name: "My Business Unit",
175
+ contactEmail: "contact@example.com",
176
+ };
177
+ const createResponse = await supertest(ctMock.app)
178
+ .post("/dummy/business-units")
179
+ .send(draft);
180
+
181
+ expect(createResponse.status).toBe(201);
182
+
183
+ const updateResponse = await supertest(ctMock.app)
184
+ .post(`/dummy/me/business-units/key=${createResponse.body.key}`)
185
+ .send({
186
+ id: createResponse.body.id,
187
+ version: createResponse.body.version,
188
+ actions: [
189
+ {
190
+ action: "changeName",
191
+ name: "Updated Business Unit Name",
192
+ },
193
+ ],
194
+ });
195
+
196
+ expect(updateResponse.status).toBe(200);
197
+ expect(updateResponse.body.name).toBe("Updated Business Unit Name");
198
+ });
113
199
  });
@@ -22,11 +22,14 @@ export class MyBusinessUnitService extends AbstractService {
22
22
  this.extraRoutes(router);
23
23
 
24
24
  router.get("/business-units/", this.get.bind(this));
25
+ router.get("/business-units/key=:key", this.getWithKey.bind(this));
25
26
  router.get("/business-units/:id", this.getWithId.bind(this));
26
27
 
28
+ router.delete("/business-units/key=:key", this.deleteWithKey.bind(this));
27
29
  router.delete("/business-units/:id", this.deleteWithId.bind(this));
28
30
 
29
31
  router.post("/business-units/", this.post.bind(this));
32
+ router.post("/business-units/key=:key", this.postWithKey.bind(this));
30
33
  router.post("/business-units/:id", this.postWithId.bind(this));
31
34
 
32
35
  parent.use(`/${basePath}`, router);
@@ -15,6 +15,8 @@ describe("Project", () => {
15
15
  carts: {
16
16
  countryTaxRateFallbackEnabled: false,
17
17
  deleteDaysAfterLastModification: 90,
18
+ priceRoundingMode: "HalfEven",
19
+ taxRoundingMode: "HalfEven",
18
20
  },
19
21
  countries: [],
20
22
  createdAt: "2018-10-04T11:32:12.603Z",
@@ -39,8 +41,14 @@ describe("Project", () => {
39
41
  productsSearch: {
40
42
  status: "Deactivated",
41
43
  },
44
+ businessUnits: {
45
+ status: "Deactivated",
46
+ },
42
47
  },
43
48
  trialUntil: "2018-12",
49
+ shoppingLists: {
50
+ deleteDaysAfterLastModification: 360,
51
+ },
44
52
  } as Project);
45
53
  });
46
54
 
@@ -80,6 +80,11 @@ export class InMemoryStorage extends AbstractStorage {
80
80
  carts: {
81
81
  countryTaxRateFallbackEnabled: false,
82
82
  deleteDaysAfterLastModification: 90,
83
+ priceRoundingMode: "HalfEven",
84
+ taxRoundingMode: "HalfEven",
85
+ },
86
+ shoppingLists: {
87
+ deleteDaysAfterLastModification: 360,
83
88
  },
84
89
  messages: { enabled: false, deleteDaysAfterCreation: 15 },
85
90
  shippingRateInputType: undefined,
@@ -97,6 +102,9 @@ export class InMemoryStorage extends AbstractStorage {
97
102
  customers: {
98
103
  status: "Deactivated",
99
104
  },
105
+ businessUnits: {
106
+ status: "Deactivated",
107
+ },
100
108
  },
101
109
  version: 1,
102
110
  };