@labdigital/commercetools-mock 2.65.1 → 3.0.0-beta.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/README.md +31 -8
- package/dist/abstract-BKFcva6S.mjs +1044 -0
- package/dist/abstract-BKFcva6S.mjs.map +1 -0
- package/dist/config-BcNSzPZz.d.mts +1718 -0
- package/dist/index.d.mts +50 -1633
- package/dist/index.mjs +3771 -2654
- package/dist/index.mjs.map +1 -1
- package/dist/storage/sqlite.d.mts +59 -0
- package/dist/storage/sqlite.mjs +234 -0
- package/dist/storage/sqlite.mjs.map +1 -0
- package/package.json +26 -29
- package/src/ctMock.ts +125 -136
- package/src/helpers.ts +14 -6
- package/src/index.ts +5 -0
- package/src/lib/masking.ts +4 -5
- package/src/lib/product-review-statistics.test.ts +257 -294
- package/src/lib/review-statistics.ts +17 -4
- package/src/oauth/helpers.ts +7 -4
- package/src/oauth/server.test.ts +102 -62
- package/src/oauth/server.ts +215 -213
- package/src/oauth/store.ts +20 -6
- package/src/orderSearch.ts +3 -3
- package/src/product-projection-search.ts +38 -20
- package/src/product-search-availability.test.ts +31 -52
- package/src/product-search.ts +19 -10
- package/src/projectAPI.ts +6 -22
- package/src/repositories/abstract.ts +182 -48
- package/src/repositories/as-associate.test.ts +19 -19
- package/src/repositories/associate-role.ts +12 -23
- package/src/repositories/attribute-group.test.ts +23 -23
- package/src/repositories/attribute-group.ts +6 -4
- package/src/repositories/business-unit.test.ts +63 -57
- package/src/repositories/business-unit.ts +107 -55
- package/src/repositories/cart/actions.ts +96 -65
- package/src/repositories/cart/helpers.ts +15 -11
- package/src/repositories/cart/index.test.ts +136 -30
- package/src/repositories/cart/index.ts +76 -59
- package/src/repositories/cart-discount/actions.ts +12 -44
- package/src/repositories/cart-discount/index.ts +20 -8
- package/src/repositories/category/actions.ts +27 -27
- package/src/repositories/category/index.test.ts +13 -9
- package/src/repositories/category/index.ts +40 -23
- package/src/repositories/channel.test.ts +53 -51
- package/src/repositories/channel.ts +12 -22
- package/src/repositories/custom-object.ts +34 -25
- package/src/repositories/customer/actions.ts +47 -25
- package/src/repositories/customer/index.test.ts +11 -11
- package/src/repositories/customer/index.ts +65 -35
- package/src/repositories/customer-group.test.ts +44 -42
- package/src/repositories/customer-group.ts +12 -22
- package/src/repositories/discount-code/actions.ts +3 -19
- package/src/repositories/discount-code/index.ts +9 -4
- package/src/repositories/discount-group/index.ts +8 -3
- package/src/repositories/extension.test.ts +27 -27
- package/src/repositories/extension.ts +10 -5
- package/src/repositories/helpers.ts +126 -47
- package/src/repositories/inventory-entry/actions.ts +3 -24
- package/src/repositories/inventory-entry/index.ts +19 -11
- package/src/repositories/my-customer.ts +13 -12
- package/src/repositories/my-order.ts +5 -2
- package/src/repositories/order/actions.ts +89 -56
- package/src/repositories/order/index.test.ts +36 -31
- package/src/repositories/order/index.ts +83 -49
- package/src/repositories/order-edit.ts +8 -3
- package/src/repositories/payment/actions.ts +64 -44
- package/src/repositories/payment/helpers.ts +3 -3
- package/src/repositories/payment/index.ts +28 -12
- package/src/repositories/product/actions.ts +133 -98
- package/src/repositories/product/helpers.ts +29 -16
- package/src/repositories/product/index.ts +42 -25
- package/src/repositories/product-discount.ts +6 -4
- package/src/repositories/product-projection.ts +41 -21
- package/src/repositories/product-selection.ts +8 -15
- package/src/repositories/product-tailoring.ts +22 -3
- package/src/repositories/product-type.ts +45 -4
- package/src/repositories/project.ts +57 -13
- package/src/repositories/quote/actions.ts +5 -28
- package/src/repositories/quote/index.ts +29 -6
- package/src/repositories/quote-request/actions.ts +5 -28
- package/src/repositories/quote-request/index.test.ts +3 -3
- package/src/repositories/quote-request/index.ts +31 -11
- package/src/repositories/quote-staged/actions.ts +5 -28
- package/src/repositories/quote-staged/index.ts +22 -8
- package/src/repositories/recurrence-policy/index.ts +6 -4
- package/src/repositories/recurring-order/actions.ts +7 -32
- package/src/repositories/recurring-order/index.ts +8 -6
- package/src/repositories/review.test.ts +147 -142
- package/src/repositories/review.ts +31 -37
- package/src/repositories/shipping-method/actions.ts +11 -28
- package/src/repositories/shipping-method/index.ts +26 -15
- package/src/repositories/shopping-list/actions.ts +21 -31
- package/src/repositories/shopping-list/index.ts +44 -22
- package/src/repositories/standalone-price.ts +6 -4
- package/src/repositories/state.ts +15 -9
- package/src/repositories/store.ts +21 -32
- package/src/repositories/subscription.test.ts +22 -22
- package/src/repositories/subscription.ts +8 -3
- package/src/repositories/tax-category/index.ts +8 -3
- package/src/repositories/type/actions.ts +21 -3
- package/src/repositories/type/index.ts +5 -3
- package/src/repositories/zone.test.ts +112 -77
- package/src/repositories/zone.ts +5 -3
- package/src/schemas/generated/associate-role.ts +13 -0
- package/src/schemas/generated/attribute-group.ts +12 -0
- package/src/schemas/generated/business-unit.ts +38 -0
- package/src/schemas/generated/cart-discount.ts +33 -0
- package/src/schemas/generated/cart.ts +61 -0
- package/src/schemas/generated/category.ts +25 -0
- package/src/schemas/generated/channel.ts +21 -0
- package/src/schemas/generated/common.ts +1372 -0
- package/src/schemas/generated/custom-object.ts +11 -0
- package/src/schemas/generated/customer-group.ts +11 -0
- package/src/schemas/generated/customer.ts +47 -0
- package/src/schemas/generated/discount-code.ts +25 -0
- package/src/schemas/generated/discount-group.ts +13 -0
- package/src/schemas/generated/extension.ts +15 -0
- package/src/schemas/generated/index.ts +42 -0
- package/src/schemas/generated/inventory-entry.ts +20 -0
- package/src/schemas/generated/my-quote-request.ts +10 -0
- package/src/schemas/generated/order-edit.ts +18 -0
- package/src/schemas/generated/order-from-cart.ts +25 -0
- package/src/schemas/generated/payment.ts +30 -0
- package/src/schemas/generated/product-discount.ts +20 -0
- package/src/schemas/generated/product-selection.ts +18 -0
- package/src/schemas/generated/product-tailoring.ts +26 -0
- package/src/schemas/generated/product-type.ts +12 -0
- package/src/schemas/generated/product.ts +37 -0
- package/src/schemas/generated/quote-request.ts +19 -0
- package/src/schemas/generated/quote.ts +18 -0
- package/src/schemas/generated/recurrence-policy.ts +15 -0
- package/src/schemas/generated/recurring-order.ts +19 -0
- package/src/schemas/generated/review.ts +24 -0
- package/src/schemas/generated/shipping-method.ts +24 -0
- package/src/schemas/generated/shopping-list.ts +28 -0
- package/src/schemas/generated/staged-quote.ts +18 -0
- package/src/schemas/generated/standalone-price.ts +32 -0
- package/src/schemas/generated/state.ts +20 -0
- package/src/schemas/generated/store.ts +23 -0
- package/src/schemas/generated/subscription.ts +20 -0
- package/src/schemas/generated/tax-category.ts +12 -0
- package/src/schemas/generated/type.ts +17 -0
- package/src/schemas/generated/zone.ts +12 -0
- package/src/schemas/update-request.ts +3 -5
- package/src/server.ts +32 -4
- package/src/services/abstract.ts +207 -101
- package/src/services/as-associate-cart.test.ts +28 -36
- package/src/services/as-associate-cart.ts +15 -12
- package/src/services/as-associate-order.test.ts +33 -40
- package/src/services/as-associate-order.ts +15 -12
- package/src/services/as-associate-quote-request.ts +15 -12
- package/src/services/as-associate-shopping-list.test.ts +25 -35
- package/src/services/as-associate-shopping-list.ts +15 -12
- package/src/services/as-associate.test.ts +21 -15
- package/src/services/as-associate.ts +23 -22
- package/src/services/associate-roles.test.ts +16 -22
- package/src/services/associate-roles.ts +2 -2
- package/src/services/attribute-group.test.ts +40 -44
- package/src/services/attribute-group.ts +2 -2
- package/src/services/business-units.test.ts +227 -163
- package/src/services/business-units.ts +2 -2
- package/src/services/cart-discount.test.ts +253 -187
- package/src/services/cart-discount.ts +2 -2
- package/src/services/cart.test.ts +833 -832
- package/src/services/cart.ts +31 -12
- package/src/services/category.test.ts +208 -130
- package/src/services/category.ts +2 -2
- package/src/services/channel.test.ts +39 -44
- package/src/services/channel.ts +2 -2
- package/src/services/custom-object.test.ts +103 -79
- package/src/services/custom-object.ts +106 -38
- package/src/services/customer-group.test.ts +39 -44
- package/src/services/customer-group.ts +2 -2
- package/src/services/customer.test.ts +357 -292
- package/src/services/customer.ts +70 -23
- package/src/services/discount-code.test.ts +57 -68
- package/src/services/discount-code.ts +2 -2
- package/src/services/discount-group.test.ts +111 -134
- package/src/services/discount-group.ts +2 -2
- package/src/services/draft-validation.test.ts +255 -0
- package/src/services/extension.test.ts +39 -44
- package/src/services/extension.ts +2 -2
- package/src/services/inventory-entry.test.ts +106 -87
- package/src/services/inventory-entry.ts +2 -2
- package/src/services/my-business-unit.test.ts +82 -112
- package/src/services/my-business-unit.ts +25 -19
- package/src/services/my-cart.test.ts +46 -41
- package/src/services/my-cart.ts +32 -28
- package/src/services/my-customer.test.ts +153 -88
- package/src/services/my-customer.ts +130 -61
- package/src/services/my-order.ts +15 -12
- package/src/services/my-payment.test.ts +30 -24
- package/src/services/my-payment.ts +2 -2
- package/src/services/my-shopping-list.ts +2 -2
- package/src/services/order.test.ts +332 -276
- package/src/services/order.ts +45 -27
- package/src/services/payment.test.ts +31 -29
- package/src/services/payment.ts +2 -2
- package/src/services/product-discount.test.ts +39 -46
- package/src/services/product-discount.ts +2 -2
- package/src/services/product-projection.test.ts +176 -166
- package/src/services/product-projection.ts +31 -15
- package/src/services/product-selection.test.ts +17 -9
- package/src/services/product-selection.ts +2 -2
- package/src/services/product-type.test.ts +80 -21
- package/src/services/product-type.ts +2 -2
- package/src/services/product.test.ts +569 -534
- package/src/services/product.ts +14 -7
- package/src/services/project.test.ts +22 -12
- package/src/services/project.ts +28 -13
- package/src/services/quote-request.test.ts +36 -39
- package/src/services/quote-request.ts +2 -2
- package/src/services/quote-staged.ts +2 -2
- package/src/services/quote.ts +2 -2
- package/src/services/recurrence-policy.test.ts +114 -139
- package/src/services/recurrence-policy.ts +2 -2
- package/src/services/recurring-order.test.ts +149 -194
- package/src/services/recurring-order.ts +2 -2
- package/src/services/reviews.test.ts +127 -106
- package/src/services/reviews.ts +2 -2
- package/src/services/shipping-method.test.ts +96 -125
- package/src/services/shipping-method.ts +24 -12
- package/src/services/shopping-list.test.ts +183 -141
- package/src/services/shopping-list.ts +2 -2
- package/src/services/standalone-price.test.ts +60 -46
- package/src/services/standalone-price.ts +2 -2
- package/src/services/state.test.ts +20 -25
- package/src/services/state.ts +2 -2
- package/src/services/store.test.ts +26 -45
- package/src/services/store.ts +2 -2
- package/src/services/subscription.test.ts +39 -44
- package/src/services/subscription.ts +2 -2
- package/src/services/tax-category.test.ts +33 -36
- package/src/services/tax-category.ts +2 -2
- package/src/services/type.test.ts +45 -44
- package/src/services/type.ts +2 -2
- package/src/services/zone.test.ts +40 -44
- package/src/services/zone.ts +2 -2
- package/src/shipping.ts +41 -11
- package/src/storage/abstract.ts +248 -17
- package/src/storage/in-memory.ts +147 -290
- package/src/storage/sqlite.ts +429 -0
- package/src/storage/storage-map.ts +75 -0
- package/src/storage/storage.test-helpers.ts +97 -0
- package/src/storage/storage.test.ts +802 -0
- package/src/testing/associate-role.ts +28 -0
- package/src/testing/attribute-group.ts +27 -0
- package/src/testing/business-unit.ts +9 -8
- package/src/testing/cart-discount.ts +34 -0
- package/src/testing/cart.ts +20 -0
- package/src/testing/category.ts +25 -0
- package/src/testing/channel.ts +23 -0
- package/src/testing/custom-object.ts +27 -0
- package/src/testing/customer-group.ts +26 -0
- package/src/testing/customer.ts +36 -33
- package/src/testing/discount-code.ts +29 -0
- package/src/testing/discount-group.ts +27 -0
- package/src/testing/extension.ts +32 -0
- package/src/testing/index.ts +33 -0
- package/src/testing/inventory-entry.ts +26 -0
- package/src/testing/order.ts +27 -0
- package/src/testing/payment.ts +23 -0
- package/src/testing/product-discount.ts +33 -0
- package/src/testing/product-selection.ts +28 -0
- package/src/testing/product-type.ts +27 -0
- package/src/testing/product.ts +38 -0
- package/src/testing/quote-request.ts +29 -0
- package/src/testing/recurrence-policy.ts +33 -0
- package/src/testing/recurring-order.ts +32 -0
- package/src/testing/review.ts +24 -0
- package/src/testing/shipping-method.ts +31 -0
- package/src/testing/shopping-list.ts +25 -0
- package/src/testing/standalone-price.ts +31 -0
- package/src/testing/state.ts +21 -0
- package/src/testing/store.ts +26 -0
- package/src/testing/subscription.ts +38 -0
- package/src/testing/tax-category.ts +27 -0
- package/src/testing/type.ts +9 -6
- package/src/testing/zone.ts +22 -0
- package/src/validate.test.ts +122 -0
- package/src/validate.ts +78 -7
- package/src/.env +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CartDraft, LineItem } from "@commercetools/platform-sdk";
|
|
2
|
+
import type { CartAddDiscountCodeAction } from "@commercetools/platform-sdk/dist/declarations/src/generated/models/cart";
|
|
2
3
|
import { beforeEach, describe, expect, test } from "vitest";
|
|
3
4
|
import type { Config } from "#src/config.ts";
|
|
4
5
|
import { getBaseResourceProperties } from "#src/helpers.ts";
|
|
@@ -20,7 +21,7 @@ describe("Cart repository", () => {
|
|
|
20
21
|
});
|
|
21
22
|
|
|
22
23
|
test("create cart in store", async () => {
|
|
23
|
-
storage.add("dummy", "product", {
|
|
24
|
+
await storage.add("dummy", "product", {
|
|
24
25
|
createdAt: "",
|
|
25
26
|
lastModifiedAt: "",
|
|
26
27
|
productType: {
|
|
@@ -83,7 +84,7 @@ describe("Cart repository", () => {
|
|
|
83
84
|
},
|
|
84
85
|
});
|
|
85
86
|
|
|
86
|
-
storage.add("dummy", "tax-category", {
|
|
87
|
+
await storage.add("dummy", "tax-category", {
|
|
87
88
|
...getBaseResourceProperties(),
|
|
88
89
|
id: "tax-category-id",
|
|
89
90
|
key: "standard-tax",
|
|
@@ -99,7 +100,7 @@ describe("Cart repository", () => {
|
|
|
99
100
|
],
|
|
100
101
|
});
|
|
101
102
|
|
|
102
|
-
storage.add("dummy", "zone", {
|
|
103
|
+
await storage.add("dummy", "zone", {
|
|
103
104
|
...getBaseResourceProperties(),
|
|
104
105
|
id: "nl-zone-id",
|
|
105
106
|
key: "nl-zone",
|
|
@@ -111,7 +112,7 @@ describe("Cart repository", () => {
|
|
|
111
112
|
],
|
|
112
113
|
});
|
|
113
114
|
|
|
114
|
-
storage.add("dummy", "shipping-method", {
|
|
115
|
+
await storage.add("dummy", "shipping-method", {
|
|
115
116
|
...getBaseResourceProperties(),
|
|
116
117
|
id: "shipping-method-id",
|
|
117
118
|
key: "standard-shipping",
|
|
@@ -239,10 +240,10 @@ describe("Cart repository", () => {
|
|
|
239
240
|
|
|
240
241
|
const ctx = { projectKey: "dummy", storeKey: "dummyStore" };
|
|
241
242
|
|
|
242
|
-
const result = repository.create(ctx, cart);
|
|
243
|
+
const result = await repository.create(ctx, cart);
|
|
243
244
|
expect(result.id).toBeDefined();
|
|
244
245
|
|
|
245
|
-
const items = repository.query(ctx);
|
|
246
|
+
const items = await repository.query(ctx);
|
|
246
247
|
expect(items.count).toBe(1);
|
|
247
248
|
|
|
248
249
|
expect(result.anonymousId).toEqual(cart.anonymousId);
|
|
@@ -281,18 +282,18 @@ describe("Cart repository", () => {
|
|
|
281
282
|
expect(result.shippingInfo?.taxRate?.name).toBe("Standard VAT");
|
|
282
283
|
});
|
|
283
284
|
|
|
284
|
-
test("create start with store from draft", () => {
|
|
285
|
+
test("create start with store from draft", async () => {
|
|
285
286
|
const ctx = { projectKey: "dummy" };
|
|
286
287
|
const draft: CartDraft = {
|
|
287
288
|
currency: "USD",
|
|
288
289
|
store: { key: "draftStore", typeId: "store" },
|
|
289
290
|
};
|
|
290
|
-
const result = repository.create(ctx, draft);
|
|
291
|
+
const result = await repository.create(ctx, draft);
|
|
291
292
|
expect(result.store).toEqual({ typeId: "store", key: "draftStore" });
|
|
292
293
|
});
|
|
293
294
|
|
|
294
295
|
test("create cart with business unit", async () => {
|
|
295
|
-
storage.add("dummy", "business-unit", {
|
|
296
|
+
await storage.add("dummy", "business-unit", {
|
|
296
297
|
...getBaseResourceProperties(),
|
|
297
298
|
unitType: "Company",
|
|
298
299
|
key: "business-unit-key",
|
|
@@ -307,6 +308,8 @@ describe("Cart repository", () => {
|
|
|
307
308
|
key: "business-unit-key",
|
|
308
309
|
},
|
|
309
310
|
approvalRuleMode: "Explicit",
|
|
311
|
+
shippingAddressIds: [],
|
|
312
|
+
billingAddressIds: [],
|
|
310
313
|
});
|
|
311
314
|
|
|
312
315
|
const cart: CartDraft = {
|
|
@@ -320,7 +323,7 @@ describe("Cart repository", () => {
|
|
|
320
323
|
|
|
321
324
|
const ctx = { projectKey: "dummy", storeKey: "dummyStore" };
|
|
322
325
|
|
|
323
|
-
const result = repository.create(ctx, cart);
|
|
326
|
+
const result = await repository.create(ctx, cart);
|
|
324
327
|
expect(result.id).toBeDefined();
|
|
325
328
|
|
|
326
329
|
expect(result.businessUnit).toEqual({
|
|
@@ -329,8 +332,8 @@ describe("Cart repository", () => {
|
|
|
329
332
|
});
|
|
330
333
|
});
|
|
331
334
|
|
|
332
|
-
test("should calculate taxed price for custom line items with tax category", () => {
|
|
333
|
-
storage.add("dummy", "tax-category", {
|
|
335
|
+
test("should calculate taxed price for custom line items with tax category", async () => {
|
|
336
|
+
await storage.add("dummy", "tax-category", {
|
|
334
337
|
...getBaseResourceProperties(),
|
|
335
338
|
id: "tax-category-with-rate",
|
|
336
339
|
key: "vat-tax",
|
|
@@ -367,7 +370,7 @@ describe("Cart repository", () => {
|
|
|
367
370
|
};
|
|
368
371
|
|
|
369
372
|
const ctx = { projectKey: "dummy", storeKey: "dummyStore" };
|
|
370
|
-
const result = repository.create(ctx, cart);
|
|
373
|
+
const result = await repository.create(ctx, cart);
|
|
371
374
|
|
|
372
375
|
expect(result.customLineItems).toHaveLength(1);
|
|
373
376
|
const customLineItem = result.customLineItems[0];
|
|
@@ -385,8 +388,8 @@ describe("Cart repository", () => {
|
|
|
385
388
|
expect(customLineItem.taxRate?.country).toBe("NL");
|
|
386
389
|
});
|
|
387
390
|
|
|
388
|
-
test("should calculate taxed price for the cart", () => {
|
|
389
|
-
storage.add("dummy", "tax-category", {
|
|
391
|
+
test("should calculate taxed price for the cart", async () => {
|
|
392
|
+
await storage.add("dummy", "tax-category", {
|
|
390
393
|
...getBaseResourceProperties(),
|
|
391
394
|
id: "cart-tax-category",
|
|
392
395
|
key: "cart-vat-tax",
|
|
@@ -423,7 +426,7 @@ describe("Cart repository", () => {
|
|
|
423
426
|
};
|
|
424
427
|
|
|
425
428
|
const ctx = { projectKey: "dummy", storeKey: "dummyStore" };
|
|
426
|
-
const result = repository.create(ctx, cart);
|
|
429
|
+
const result = await repository.create(ctx, cart);
|
|
427
430
|
|
|
428
431
|
expect(result.taxedPrice).toBeDefined();
|
|
429
432
|
expect(result.taxedPrice?.totalNet.centAmount).toBe(1000);
|
|
@@ -439,8 +442,8 @@ describe("createShippingInfo", () => {
|
|
|
439
442
|
const config: Config = { storage, strict: false };
|
|
440
443
|
const repository = new CartRepository(config);
|
|
441
444
|
|
|
442
|
-
beforeEach(() => {
|
|
443
|
-
storage.add("dummy", "tax-category", {
|
|
445
|
+
beforeEach(async () => {
|
|
446
|
+
await storage.add("dummy", "tax-category", {
|
|
444
447
|
...getBaseResourceProperties(),
|
|
445
448
|
id: "shipping-tax-category-id",
|
|
446
449
|
key: "shipping-tax",
|
|
@@ -456,7 +459,7 @@ describe("createShippingInfo", () => {
|
|
|
456
459
|
],
|
|
457
460
|
});
|
|
458
461
|
|
|
459
|
-
storage.add("dummy", "zone", {
|
|
462
|
+
await storage.add("dummy", "zone", {
|
|
460
463
|
...getBaseResourceProperties(),
|
|
461
464
|
id: "test-zone-id",
|
|
462
465
|
name: "Test Zone",
|
|
@@ -468,8 +471,8 @@ describe("createShippingInfo", () => {
|
|
|
468
471
|
});
|
|
469
472
|
});
|
|
470
473
|
|
|
471
|
-
test("should calculate shipping info", () => {
|
|
472
|
-
storage.add("dummy", "shipping-method", {
|
|
474
|
+
test("should calculate shipping info", async () => {
|
|
475
|
+
await storage.add("dummy", "shipping-method", {
|
|
473
476
|
...getBaseResourceProperties(),
|
|
474
477
|
id: "basic-shipping-id",
|
|
475
478
|
name: "Standard Shipping",
|
|
@@ -533,7 +536,7 @@ describe("createShippingInfo", () => {
|
|
|
533
536
|
id: "basic-shipping-id",
|
|
534
537
|
};
|
|
535
538
|
|
|
536
|
-
const result = repository.createShippingInfo(
|
|
539
|
+
const result = await repository.createShippingInfo(
|
|
537
540
|
context,
|
|
538
541
|
cart,
|
|
539
542
|
shippingMethodRef,
|
|
@@ -547,8 +550,8 @@ describe("createShippingInfo", () => {
|
|
|
547
550
|
expect(result.taxedPrice!.totalGross.centAmount).toBe(720);
|
|
548
551
|
});
|
|
549
552
|
|
|
550
|
-
test("should apply free shipping when cart total is above freeAbove threshold", () => {
|
|
551
|
-
storage.add("dummy", "shipping-method", {
|
|
553
|
+
test("should apply free shipping when cart total is above freeAbove threshold", async () => {
|
|
554
|
+
await storage.add("dummy", "shipping-method", {
|
|
552
555
|
...getBaseResourceProperties(),
|
|
553
556
|
id: "free-above-shipping-id",
|
|
554
557
|
key: "free-above-shipping",
|
|
@@ -620,7 +623,7 @@ describe("createShippingInfo", () => {
|
|
|
620
623
|
id: "free-above-shipping-id",
|
|
621
624
|
};
|
|
622
625
|
|
|
623
|
-
const result = repository.createShippingInfo(
|
|
626
|
+
const result = await repository.createShippingInfo(
|
|
624
627
|
context,
|
|
625
628
|
cart,
|
|
626
629
|
shippingMethodRef,
|
|
@@ -632,8 +635,8 @@ describe("createShippingInfo", () => {
|
|
|
632
635
|
expect(result.taxedPrice!.totalNet.centAmount).toBe(0);
|
|
633
636
|
});
|
|
634
637
|
|
|
635
|
-
test("should charge normal shipping when cart total is below freeAbove threshold", () => {
|
|
636
|
-
storage.add("dummy", "shipping-method", {
|
|
638
|
+
test("should charge normal shipping when cart total is below freeAbove threshold", async () => {
|
|
639
|
+
await storage.add("dummy", "shipping-method", {
|
|
637
640
|
...getBaseResourceProperties(),
|
|
638
641
|
id: "free-above-shipping-id-2",
|
|
639
642
|
key: "free-above-shipping-2",
|
|
@@ -705,7 +708,7 @@ describe("createShippingInfo", () => {
|
|
|
705
708
|
id: "free-above-shipping-id-2",
|
|
706
709
|
};
|
|
707
710
|
|
|
708
|
-
const result = repository.createShippingInfo(
|
|
711
|
+
const result = await repository.createShippingInfo(
|
|
709
712
|
context,
|
|
710
713
|
cart,
|
|
711
714
|
shippingMethodRef,
|
|
@@ -718,7 +721,7 @@ describe("createShippingInfo", () => {
|
|
|
718
721
|
});
|
|
719
722
|
|
|
720
723
|
test("create cart with discount code", async () => {
|
|
721
|
-
const code = storage.add("dummy", "discount-code", {
|
|
724
|
+
const code = await storage.add("dummy", "discount-code", {
|
|
722
725
|
...getBaseResourceProperties(),
|
|
723
726
|
code: "test-1234",
|
|
724
727
|
cartDiscounts: [],
|
|
@@ -735,7 +738,7 @@ describe("createShippingInfo", () => {
|
|
|
735
738
|
|
|
736
739
|
const ctx = { projectKey: "dummy", storeKey: "dummyStore" };
|
|
737
740
|
|
|
738
|
-
const result = repository.create(ctx, cart);
|
|
741
|
+
const result = await repository.create(ctx, cart);
|
|
739
742
|
expect(result.id).toBeDefined();
|
|
740
743
|
|
|
741
744
|
expect(result.discountCodes).toEqual([
|
|
@@ -748,4 +751,107 @@ describe("createShippingInfo", () => {
|
|
|
748
751
|
},
|
|
749
752
|
]);
|
|
750
753
|
});
|
|
754
|
+
|
|
755
|
+
test("create cart with non-existent discount code throws error", async () => {
|
|
756
|
+
const cart: CartDraft = {
|
|
757
|
+
country: "NL",
|
|
758
|
+
currency: "EUR",
|
|
759
|
+
discountCodes: ["non-existent-code"],
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
const ctx = { projectKey: "dummy", storeKey: "dummyStore" };
|
|
763
|
+
|
|
764
|
+
await expect(repository.create(ctx, cart)).rejects.toThrow(
|
|
765
|
+
"The discount code 'non-existent-code' was not found.",
|
|
766
|
+
);
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
test("create cart with duplicate discount codes deduplicates them", async () => {
|
|
770
|
+
const code = await storage.add("dummy", "discount-code", {
|
|
771
|
+
...getBaseResourceProperties(),
|
|
772
|
+
code: "duplicate-test",
|
|
773
|
+
cartDiscounts: [],
|
|
774
|
+
isActive: true,
|
|
775
|
+
references: [],
|
|
776
|
+
groups: [],
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
const cart: CartDraft = {
|
|
780
|
+
country: "NL",
|
|
781
|
+
currency: "EUR",
|
|
782
|
+
discountCodes: ["duplicate-test", "duplicate-test"],
|
|
783
|
+
};
|
|
784
|
+
|
|
785
|
+
const ctx = { projectKey: "dummy", storeKey: "dummyStore" };
|
|
786
|
+
|
|
787
|
+
const result = await repository.create(ctx, cart);
|
|
788
|
+
expect(result.discountCodes).toHaveLength(1);
|
|
789
|
+
expect(result.discountCodes).toEqual([
|
|
790
|
+
{
|
|
791
|
+
discountCode: {
|
|
792
|
+
typeId: "discount-code",
|
|
793
|
+
id: code.id,
|
|
794
|
+
},
|
|
795
|
+
state: "MatchesCart",
|
|
796
|
+
},
|
|
797
|
+
]);
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
test("addDiscountCode action adds discount code to cart", async () => {
|
|
801
|
+
const code = await storage.add("dummy", "discount-code", {
|
|
802
|
+
...getBaseResourceProperties(),
|
|
803
|
+
code: "action-test-code",
|
|
804
|
+
cartDiscounts: [],
|
|
805
|
+
isActive: true,
|
|
806
|
+
references: [],
|
|
807
|
+
groups: [],
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
const cart: CartDraft = {
|
|
811
|
+
country: "NL",
|
|
812
|
+
currency: "EUR",
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
const ctx = { projectKey: "dummy", storeKey: "dummyStore" };
|
|
816
|
+
|
|
817
|
+
const createdCart = await repository.create(ctx, cart);
|
|
818
|
+
expect(createdCart.discountCodes).toHaveLength(0);
|
|
819
|
+
|
|
820
|
+
const updatedCart = await repository.processUpdateActions(
|
|
821
|
+
ctx,
|
|
822
|
+
createdCart,
|
|
823
|
+
createdCart.version,
|
|
824
|
+
[
|
|
825
|
+
{
|
|
826
|
+
action: "addDiscountCode",
|
|
827
|
+
code: "action-test-code",
|
|
828
|
+
} as CartAddDiscountCodeAction,
|
|
829
|
+
],
|
|
830
|
+
);
|
|
831
|
+
|
|
832
|
+
expect(updatedCart.discountCodes).toEqual([
|
|
833
|
+
{
|
|
834
|
+
discountCode: {
|
|
835
|
+
typeId: "discount-code",
|
|
836
|
+
id: code.id,
|
|
837
|
+
},
|
|
838
|
+
state: "MatchesCart",
|
|
839
|
+
},
|
|
840
|
+
]);
|
|
841
|
+
|
|
842
|
+
// Adding the same discount code again should not create a duplicate
|
|
843
|
+
const updatedCart2 = await repository.processUpdateActions(
|
|
844
|
+
ctx,
|
|
845
|
+
updatedCart,
|
|
846
|
+
updatedCart.version,
|
|
847
|
+
[
|
|
848
|
+
{
|
|
849
|
+
action: "addDiscountCode",
|
|
850
|
+
code: "action-test-code",
|
|
851
|
+
} as CartAddDiscountCodeAction,
|
|
852
|
+
],
|
|
853
|
+
);
|
|
854
|
+
|
|
855
|
+
expect(updatedCart2.discountCodes).toHaveLength(1);
|
|
856
|
+
});
|
|
751
857
|
});
|
|
@@ -8,14 +8,15 @@ import type {
|
|
|
8
8
|
LineItem,
|
|
9
9
|
LineItemDraft,
|
|
10
10
|
Product,
|
|
11
|
-
ProductPagedQueryResponse,
|
|
12
11
|
ShippingMethodDoesNotMatchCartError,
|
|
13
12
|
} from "@commercetools/platform-sdk";
|
|
13
|
+
|
|
14
14
|
import { v4 as uuidv4 } from "uuid";
|
|
15
15
|
import type { Config } from "#src/config.ts";
|
|
16
16
|
import { CommercetoolsError } from "#src/exceptions.ts";
|
|
17
17
|
import { getBaseResourceProperties } from "#src/helpers.ts";
|
|
18
18
|
import { calculateTaxTotals } from "#src/lib/tax.ts";
|
|
19
|
+
import { CartDraftSchema } from "#src/schemas/generated/cart.ts";
|
|
19
20
|
import {
|
|
20
21
|
createShippingInfoFromMethod,
|
|
21
22
|
getShippingMethodsMatchingCart,
|
|
@@ -43,9 +44,10 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
43
44
|
constructor(config: Config) {
|
|
44
45
|
super("cart", config);
|
|
45
46
|
this.actions = new CartUpdateHandler(this._storage, this);
|
|
47
|
+
this.draftSchema = CartDraftSchema;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
|
-
create(context: RepositoryContext, draft: CartDraft): Cart {
|
|
50
|
+
async create(context: RepositoryContext, draft: CartDraft): Promise<Cart> {
|
|
49
51
|
if (draft.anonymousId && draft.customerId) {
|
|
50
52
|
throw new CommercetoolsError<InvalidOperationError>({
|
|
51
53
|
code: "InvalidOperation",
|
|
@@ -55,7 +57,7 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
55
57
|
|
|
56
58
|
// Validate that the customer exists
|
|
57
59
|
if (draft.customerId) {
|
|
58
|
-
this._storage.getByResourceIdentifier(context.projectKey, {
|
|
60
|
+
await this._storage.getByResourceIdentifier(context.projectKey, {
|
|
59
61
|
typeId: "customer",
|
|
60
62
|
id: draft.customerId,
|
|
61
63
|
});
|
|
@@ -64,7 +66,7 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
64
66
|
let storedBusinessUnit: BusinessUnit | undefined;
|
|
65
67
|
if (draft.businessUnit?.id || draft.businessUnit?.key) {
|
|
66
68
|
storedBusinessUnit =
|
|
67
|
-
this._storage.getByResourceIdentifier<"business-unit">(
|
|
69
|
+
await this._storage.getByResourceIdentifier<"business-unit">(
|
|
68
70
|
context.projectKey,
|
|
69
71
|
{
|
|
70
72
|
typeId: "business-unit",
|
|
@@ -74,42 +76,51 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
74
76
|
);
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
const lineItems =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
const lineItems = draft.lineItems
|
|
80
|
+
? await Promise.all(
|
|
81
|
+
draft.lineItems.map((draftLineItem) =>
|
|
82
|
+
this.draftLineItemtoLineItem(
|
|
83
|
+
context.projectKey,
|
|
84
|
+
draftLineItem,
|
|
85
|
+
draft.currency,
|
|
86
|
+
draft.country,
|
|
87
|
+
),
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
: [];
|
|
86
91
|
|
|
87
|
-
const customLineItems =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
const customLineItems = draft.customLineItems
|
|
93
|
+
? await Promise.all(
|
|
94
|
+
draft.customLineItems.map((draftCustomLineItem) =>
|
|
95
|
+
createCustomLineItemFromDraft(
|
|
96
|
+
context.projectKey,
|
|
97
|
+
draftCustomLineItem,
|
|
98
|
+
this._storage,
|
|
99
|
+
draft.shippingAddress?.country ?? draft.country,
|
|
100
|
+
),
|
|
101
|
+
),
|
|
102
|
+
)
|
|
103
|
+
: [];
|
|
96
104
|
|
|
97
|
-
// Validate that discount codes exist
|
|
105
|
+
// Validate that discount codes exist and deduplicate
|
|
98
106
|
const discountCodeInfo: DiscountCodeInfo[] = [];
|
|
99
107
|
if (draft.discountCodes?.length) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
),
|
|
108
|
+
const seen = new Set<string>();
|
|
109
|
+
for (const code of draft.discountCodes) {
|
|
110
|
+
const info = await createDiscountCodeInfoFromCode(
|
|
111
|
+
context.projectKey,
|
|
112
|
+
this._storage,
|
|
113
|
+
code,
|
|
107
114
|
);
|
|
108
|
-
|
|
115
|
+
if (!seen.has(info.discountCode.id)) {
|
|
116
|
+
seen.add(info.discountCode.id);
|
|
117
|
+
discountCodeInfo.push(info);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
109
120
|
}
|
|
110
121
|
|
|
111
122
|
const resource: Writable<Cart> = {
|
|
112
|
-
...getBaseResourceProperties(),
|
|
123
|
+
...getBaseResourceProperties(context.clientId),
|
|
113
124
|
anonymousId: draft.anonymousId,
|
|
114
125
|
businessUnit:
|
|
115
126
|
storedBusinessUnit && draft.businessUnit
|
|
@@ -154,7 +165,7 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
154
165
|
shippingInfo: undefined,
|
|
155
166
|
origin: draft.origin ?? "Customer",
|
|
156
167
|
refusedGifts: [],
|
|
157
|
-
custom: createCustomFields(
|
|
168
|
+
custom: await createCustomFields(
|
|
158
169
|
draft.custom,
|
|
159
170
|
context.projectKey,
|
|
160
171
|
this._storage,
|
|
@@ -169,7 +180,7 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
169
180
|
|
|
170
181
|
// Set shipping info after resource is created
|
|
171
182
|
if (draft.shippingMethod) {
|
|
172
|
-
resource.shippingInfo = this.createShippingInfo(
|
|
183
|
+
resource.shippingInfo = await this.createShippingInfo(
|
|
173
184
|
context,
|
|
174
185
|
resource,
|
|
175
186
|
draft.shippingMethod,
|
|
@@ -180,12 +191,12 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
180
191
|
resource.taxedPrice = taxedPrice;
|
|
181
192
|
resource.taxedShippingPrice = taxedShippingPrice;
|
|
182
193
|
|
|
183
|
-
return this.saveNew(context, resource);
|
|
194
|
+
return await this.saveNew(context, resource);
|
|
184
195
|
}
|
|
185
196
|
|
|
186
|
-
getActiveCart(projectKey: string): Cart | undefined {
|
|
197
|
+
async getActiveCart(projectKey: string): Promise<Cart | undefined> {
|
|
187
198
|
// Get first active cart
|
|
188
|
-
const results = this._storage.query(projectKey, this.getTypeId(), {
|
|
199
|
+
const results = await this._storage.query(projectKey, this.getTypeId(), {
|
|
189
200
|
where: [`cartState="Active"`],
|
|
190
201
|
});
|
|
191
202
|
if (results.count > 0) {
|
|
@@ -195,26 +206,26 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
195
206
|
return;
|
|
196
207
|
}
|
|
197
208
|
|
|
198
|
-
draftLineItemtoLineItem = (
|
|
209
|
+
draftLineItemtoLineItem = async (
|
|
199
210
|
projectKey: string,
|
|
200
211
|
draftLineItem: LineItemDraft,
|
|
201
212
|
currency: string,
|
|
202
213
|
country: string | undefined,
|
|
203
|
-
): LineItem => {
|
|
214
|
+
): Promise<LineItem> => {
|
|
204
215
|
const { productId, quantity, variantId, sku } = draftLineItem;
|
|
205
216
|
|
|
206
217
|
let product: Product | null = null;
|
|
207
218
|
|
|
208
219
|
if (productId && variantId) {
|
|
209
220
|
// Fetch product and variant by ID
|
|
210
|
-
product = this._storage.get(projectKey, "product", productId, {});
|
|
221
|
+
product = await this._storage.get(projectKey, "product", productId, {});
|
|
211
222
|
} else if (sku) {
|
|
212
223
|
// Fetch product and variant by SKU
|
|
213
|
-
const items = this._storage.query(projectKey, "product", {
|
|
224
|
+
const items = await this._storage.query(projectKey, "product", {
|
|
214
225
|
where: [
|
|
215
226
|
`masterData(current(masterVariant(sku="${sku}"))) or masterData(current(variants(sku="${sku}")))`,
|
|
216
227
|
],
|
|
217
|
-
})
|
|
228
|
+
});
|
|
218
229
|
|
|
219
230
|
if (items.count === 1) {
|
|
220
231
|
product = items.results[0];
|
|
@@ -243,20 +254,22 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
243
254
|
|
|
244
255
|
if (!variant) {
|
|
245
256
|
// Check if variant is found
|
|
246
|
-
throw new
|
|
247
|
-
|
|
257
|
+
throw new CommercetoolsError<InvalidOperationError>({
|
|
258
|
+
code: "InvalidOperation",
|
|
259
|
+
message: sku
|
|
248
260
|
? `A variant with SKU '${sku}' for product '${product.id}' not found.`
|
|
249
261
|
: `A variant with ID '${variantId}' for product '${product.id}' not found.`,
|
|
250
|
-
);
|
|
262
|
+
});
|
|
251
263
|
}
|
|
252
264
|
|
|
253
265
|
const quant = quantity ?? 1;
|
|
254
266
|
|
|
255
267
|
const price = selectPrice({ prices: variant.prices, currency, country });
|
|
256
268
|
if (!price) {
|
|
257
|
-
throw new
|
|
258
|
-
|
|
259
|
-
|
|
269
|
+
throw new CommercetoolsError<InvalidOperationError>({
|
|
270
|
+
code: "InvalidOperation",
|
|
271
|
+
message: `No valid price found for ${productId} for country ${country} and currency ${currency}`,
|
|
272
|
+
});
|
|
260
273
|
}
|
|
261
274
|
|
|
262
275
|
const totalPrice = createCentPrecisionMoney({
|
|
@@ -281,7 +294,7 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
281
294
|
lineItemMode: "Standard",
|
|
282
295
|
priceMode: "Platform",
|
|
283
296
|
state: [],
|
|
284
|
-
custom: createCustomFields(
|
|
297
|
+
custom: await createCustomFields(
|
|
285
298
|
draftLineItem.custom,
|
|
286
299
|
projectKey,
|
|
287
300
|
this._storage,
|
|
@@ -289,25 +302,28 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
289
302
|
};
|
|
290
303
|
};
|
|
291
304
|
|
|
292
|
-
createShippingInfo(
|
|
305
|
+
async createShippingInfo(
|
|
293
306
|
context: RepositoryContext,
|
|
294
307
|
resource: Writable<Cart>,
|
|
295
308
|
shippingMethodRef: NonNullable<CartDraft["shippingMethod"]>,
|
|
296
|
-
): NonNullable<Cart["shippingInfo"]
|
|
309
|
+
): Promise<NonNullable<Cart["shippingInfo"]>> {
|
|
297
310
|
if (resource.taxMode === "External") {
|
|
298
|
-
throw new
|
|
311
|
+
throw new CommercetoolsError<InvalidOperationError>({
|
|
312
|
+
code: "InvalidOperation",
|
|
313
|
+
message: "External tax rate is not supported",
|
|
314
|
+
});
|
|
299
315
|
}
|
|
300
316
|
|
|
301
317
|
// Bit of a hack: calling this checks that the resource identifier is
|
|
302
318
|
// valid (i.e. id xor key) and that the shipping method exists.
|
|
303
|
-
this._storage.getByResourceIdentifier<"shipping-method">(
|
|
319
|
+
await this._storage.getByResourceIdentifier<"shipping-method">(
|
|
304
320
|
context.projectKey,
|
|
305
321
|
shippingMethodRef,
|
|
306
322
|
);
|
|
307
323
|
|
|
308
324
|
// getShippingMethodsMatchingCart does the work of determining whether the
|
|
309
325
|
// shipping method is allowed for the cart, and which shipping rate to use
|
|
310
|
-
const shippingMethods = getShippingMethodsMatchingCart(
|
|
326
|
+
const shippingMethods = await getShippingMethodsMatchingCart(
|
|
311
327
|
context,
|
|
312
328
|
this._storage,
|
|
313
329
|
resource,
|
|
@@ -316,10 +332,11 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
316
332
|
},
|
|
317
333
|
);
|
|
318
334
|
|
|
319
|
-
const method = shippingMethods.results.find(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
335
|
+
const method = shippingMethods.results.find(
|
|
336
|
+
(candidate: { id: string; key?: string }) =>
|
|
337
|
+
shippingMethodRef.id
|
|
338
|
+
? candidate.id === shippingMethodRef.id
|
|
339
|
+
: candidate.key === shippingMethodRef.key,
|
|
323
340
|
);
|
|
324
341
|
|
|
325
342
|
// Not finding the method in the results means it's not allowed, since
|
|
@@ -333,7 +350,7 @@ export class CartRepository extends AbstractResourceRepository<"cart"> {
|
|
|
333
350
|
}
|
|
334
351
|
|
|
335
352
|
// Use the shared shipping info creation logic
|
|
336
|
-
return createShippingInfoFromMethod(
|
|
353
|
+
return await createShippingInfoFromMethod(
|
|
337
354
|
context,
|
|
338
355
|
this._storage,
|
|
339
356
|
resource,
|