@labdigital/commercetools-mock 2.56.1 → 2.57.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@labdigital/commercetools-mock",
3
- "version": "2.56.1",
3
+ "version": "2.57.1",
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",
@@ -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,3 +1,4 @@
1
+ import { beforeEach } from "node:test";
1
2
  import type {
2
3
  Cart,
3
4
  LineItem,
@@ -5,6 +6,7 @@ import type {
5
6
  } from "@commercetools/platform-sdk";
6
7
  import { describe, expect, test } from "vitest";
7
8
  import type { Config } from "~src/config";
9
+ import { getBaseResourceProperties } from "~src/helpers";
8
10
  import { InMemoryStorage } from "~src/storage";
9
11
  import { OrderRepository } from "./index";
10
12
 
@@ -16,6 +18,10 @@ describe("Order repository", () => {
16
18
  };
17
19
  const repository = new OrderRepository(config);
18
20
 
21
+ beforeEach(() => {
22
+ storage.clear();
23
+ });
24
+
19
25
  test("create from cart", async () => {
20
26
  const cart: Cart = {
21
27
  id: "b3875a58-4ab2-4aaa-b399-184ce7561c27",
@@ -183,6 +189,88 @@ describe("Order repository", () => {
183
189
  expect(result.store).toEqual(cart.store);
184
190
  });
185
191
 
192
+ test("create order in store", async () => {
193
+ storage.add("dummy", "store", {
194
+ ...getBaseResourceProperties(),
195
+ id: "store-123",
196
+ key: "testStore",
197
+ name: { "en-US": "Test Store" },
198
+ countries: [{ code: "NL" }],
199
+ languages: ["en-US"],
200
+ distributionChannels: [],
201
+ supplyChannels: [],
202
+ productSelections: [],
203
+ });
204
+
205
+ storage.add("dummy", "business-unit", {
206
+ ...getBaseResourceProperties(),
207
+ id: "business-unit-123",
208
+ unitType: "Company",
209
+ key: "test-business-unit",
210
+ status: "Active",
211
+ storeMode: "Explicit",
212
+ name: "Test Business Unit",
213
+ addresses: [],
214
+ associateMode: "Explicit",
215
+ associates: [],
216
+ topLevelUnit: {
217
+ typeId: "business-unit",
218
+ key: "test-business-unit",
219
+ },
220
+ approvalRuleMode: "Explicit",
221
+ });
222
+
223
+ storage.add("dummy", "customer", {
224
+ ...getBaseResourceProperties(),
225
+ id: "customer-123",
226
+ email: "test@example.com",
227
+ firstName: "John",
228
+ lastName: "Doe",
229
+ password: "hashed-password",
230
+ addresses: [],
231
+ defaultShippingAddressId: "",
232
+ defaultBillingAddressId: "",
233
+ customerNumber: "CUST-001",
234
+ externalId: "",
235
+ key: "test-customer",
236
+ stores: [],
237
+ isEmailVerified: true,
238
+ authenticationMode: "Password" as const,
239
+ });
240
+
241
+ const draft: OrderImportDraft = {
242
+ orderNumber: "100000002",
243
+ totalPrice: {
244
+ centAmount: 1000,
245
+ currencyCode: "EUR",
246
+ },
247
+ paymentState: "Paid",
248
+ customLineItems: [],
249
+ lineItems: [],
250
+ store: {
251
+ typeId: "store",
252
+ key: "testStore",
253
+ },
254
+ businessUnit: {
255
+ typeId: "business-unit",
256
+ key: "test-business-unit",
257
+ },
258
+ customerId: "customer-123",
259
+ };
260
+
261
+ const ctx = { projectKey: "dummy", storeKey: "testStore" };
262
+ const result = repository.import(ctx, draft);
263
+
264
+ expect(result.orderNumber).toBe("100000002");
265
+ expect(result.store?.key).toBe("testStore");
266
+ expect(result.businessUnit?.key).toBe("test-business-unit");
267
+ expect(result.customerId).toBe("customer-123");
268
+ expect(result.totalPrice.centAmount).toBe(1000);
269
+ expect(result.totalPrice.currencyCode).toBe("EUR");
270
+ expect(result.orderState).toBe("Open");
271
+ expect(result.paymentState).toBe("Paid");
272
+ });
273
+
186
274
  test("import exiting product", async () => {
187
275
  storage.add("dummy", "product", {
188
276
  id: "15fc56ba-a74e-4cf8-b4b0-bada5c101541",
@@ -120,6 +120,10 @@ export class OrderRepository extends AbstractResourceRepository<"order"> {
120
120
  this._storage,
121
121
  ),
122
122
  customerEmail: draft.customerEmail,
123
+ customerId: draft.customerId,
124
+ businessUnit: draft.businessUnit?.key
125
+ ? { typeId: "business-unit", key: draft.businessUnit.key }
126
+ : undefined,
123
127
  lastMessageSequenceNumber: 0,
124
128
  orderNumber: draft.orderNumber,
125
129
  orderState: draft.orderState || "Open",
@@ -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>,
@@ -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
  };