@labdigital/commercetools-mock 2.66.0 → 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 +3769 -2653
- 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 +84 -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,16 +1,16 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
Product,
|
|
3
|
-
ProductDraft,
|
|
4
3
|
ProductProjection,
|
|
5
4
|
ProductProjectionPagedSearchResponse,
|
|
6
5
|
ProductType,
|
|
7
|
-
ProductTypeDraft,
|
|
8
6
|
} from "@commercetools/platform-sdk";
|
|
9
|
-
import supertest from "supertest";
|
|
10
7
|
import * as timekeeper from "timekeeper";
|
|
11
8
|
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
9
|
+
import {
|
|
10
|
+
productDraftFactory,
|
|
11
|
+
productTypeDraftFactory,
|
|
12
|
+
} from "#src/testing/index.ts";
|
|
12
13
|
import { CommercetoolsMock } from "../index.ts";
|
|
13
|
-
import type { Writable } from "../types.ts";
|
|
14
14
|
|
|
15
15
|
const ctMock = new CommercetoolsMock();
|
|
16
16
|
|
|
@@ -19,68 +19,55 @@ let productProjection: ProductProjection;
|
|
|
19
19
|
let publishedProduct: Product;
|
|
20
20
|
let unpublishedProduct: Product;
|
|
21
21
|
|
|
22
|
+
const productTypeFactory = productTypeDraftFactory(ctMock);
|
|
23
|
+
const productFactory = productDraftFactory(ctMock);
|
|
24
|
+
|
|
22
25
|
beforeEach(async () => {
|
|
23
26
|
timekeeper.freeze(new Date("2022-07-22T13:31:49.840Z"));
|
|
24
27
|
|
|
25
28
|
// Create the product type
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
};
|
|
31
|
-
const response = await supertest(ctMock.app)
|
|
32
|
-
.post("/dummy/product-types")
|
|
33
|
-
.send(draft);
|
|
34
|
-
|
|
35
|
-
expect(response.ok).toBe(true);
|
|
36
|
-
productType = response.body;
|
|
37
|
-
}
|
|
29
|
+
productType = await productTypeFactory.create({
|
|
30
|
+
name: "Default Product Type",
|
|
31
|
+
description: "Product type for testing",
|
|
32
|
+
});
|
|
38
33
|
|
|
39
34
|
// Create an unpublished product
|
|
40
|
-
{
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
{
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
centAmount: 189,
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
],
|
|
55
|
-
attributes: [
|
|
56
|
-
{
|
|
57
|
-
name: "number",
|
|
58
|
-
value: 1 as any,
|
|
35
|
+
unpublishedProduct = await productFactory.create({
|
|
36
|
+
publish: false,
|
|
37
|
+
key: "my-unpublished-product",
|
|
38
|
+
attributes: [{ name: "number", value: 11 as any }],
|
|
39
|
+
masterVariant: {
|
|
40
|
+
sku: "my-unpub-sku",
|
|
41
|
+
prices: [
|
|
42
|
+
{
|
|
43
|
+
value: {
|
|
44
|
+
currencyCode: "EUR",
|
|
45
|
+
centAmount: 189,
|
|
59
46
|
},
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
attributes: [
|
|
50
|
+
{
|
|
51
|
+
name: "number",
|
|
52
|
+
value: 1 as any,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
name: {
|
|
57
|
+
"nl-NL": "test unpublished product",
|
|
58
|
+
},
|
|
59
|
+
productType: {
|
|
60
|
+
typeId: "product-type",
|
|
61
|
+
id: productType.id,
|
|
62
|
+
},
|
|
63
|
+
slug: {
|
|
64
|
+
"nl-NL": "test-unpublished-product",
|
|
65
|
+
},
|
|
66
|
+
});
|
|
80
67
|
|
|
81
68
|
// Create a published product
|
|
82
69
|
{
|
|
83
|
-
const productDraft
|
|
70
|
+
const productDraft = {
|
|
84
71
|
publish: true,
|
|
85
72
|
key: "my-product-key",
|
|
86
73
|
attributes: [{ name: "number", value: 111 as any }],
|
|
@@ -128,7 +115,7 @@ beforeEach(async () => {
|
|
|
128
115
|
"nl-NL": "test product",
|
|
129
116
|
},
|
|
130
117
|
productType: {
|
|
131
|
-
typeId: "product-type",
|
|
118
|
+
typeId: "product-type" as const,
|
|
132
119
|
id: productType.id,
|
|
133
120
|
},
|
|
134
121
|
slug: {
|
|
@@ -136,12 +123,8 @@ beforeEach(async () => {
|
|
|
136
123
|
},
|
|
137
124
|
};
|
|
138
125
|
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
.send(productDraft);
|
|
142
|
-
expect(response.ok).toBe(true);
|
|
143
|
-
const product = response.body;
|
|
144
|
-
publishedProduct = response.body;
|
|
126
|
+
const product = await productFactory.create(productDraft);
|
|
127
|
+
publishedProduct = product;
|
|
145
128
|
|
|
146
129
|
// Create the expected ProductProjection object
|
|
147
130
|
productProjection = {
|
|
@@ -158,7 +141,7 @@ beforeEach(async () => {
|
|
|
158
141
|
sku: "my-sku",
|
|
159
142
|
prices: [
|
|
160
143
|
{
|
|
161
|
-
id: product.masterData.current.masterVariant.prices[0].id,
|
|
144
|
+
id: product.masterData.current.masterVariant.prices![0].id,
|
|
162
145
|
value: {
|
|
163
146
|
type: "centPrecision",
|
|
164
147
|
currencyCode: "EUR",
|
|
@@ -177,7 +160,7 @@ beforeEach(async () => {
|
|
|
177
160
|
sku: "my-other-sku",
|
|
178
161
|
prices: [
|
|
179
162
|
{
|
|
180
|
-
id: product.masterData.current.variants[0].prices[0].id,
|
|
163
|
+
id: product.masterData.current.variants[0].prices![0].id,
|
|
181
164
|
value: {
|
|
182
165
|
type: "centPrecision",
|
|
183
166
|
currencyCode: "EUR",
|
|
@@ -191,8 +174,8 @@ beforeEach(async () => {
|
|
|
191
174
|
attributes: productDraft.variants?.[0].attributes,
|
|
192
175
|
},
|
|
193
176
|
],
|
|
194
|
-
name:
|
|
195
|
-
slug:
|
|
177
|
+
name: product.masterData.current.name,
|
|
178
|
+
slug: product.masterData.current.slug,
|
|
196
179
|
categories: [],
|
|
197
180
|
productType: {
|
|
198
181
|
typeId: "product-type",
|
|
@@ -204,16 +187,17 @@ beforeEach(async () => {
|
|
|
204
187
|
|
|
205
188
|
afterEach(async () => {
|
|
206
189
|
timekeeper.reset();
|
|
207
|
-
ctMock.clear();
|
|
190
|
+
await ctMock.clear();
|
|
208
191
|
});
|
|
209
192
|
// Test the general product projection implementation
|
|
210
193
|
describe("Product Projection Get By ID", () => {
|
|
211
194
|
test("Get By ID", async () => {
|
|
212
|
-
const response = await
|
|
213
|
-
|
|
214
|
-
|
|
195
|
+
const response = await ctMock.app.inject({
|
|
196
|
+
method: "GET",
|
|
197
|
+
url: `/dummy/product-projections/${publishedProduct.id}`,
|
|
198
|
+
});
|
|
215
199
|
|
|
216
|
-
const result: ProductProjection = response.
|
|
200
|
+
const result: ProductProjection = response.json();
|
|
217
201
|
|
|
218
202
|
expect(result).toBeDefined();
|
|
219
203
|
expect(result.id).toBe(publishedProduct.id);
|
|
@@ -223,13 +207,15 @@ describe("Product Projection Get By ID", () => {
|
|
|
223
207
|
// Test the general product projection implementation
|
|
224
208
|
describe("Product Projection Query - Generic", () => {
|
|
225
209
|
test("Filter out staged", async () => {
|
|
226
|
-
const response = await
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
210
|
+
const response = await ctMock.app.inject({
|
|
211
|
+
method: "GET",
|
|
212
|
+
url: "/dummy/product-projections",
|
|
213
|
+
query: {
|
|
214
|
+
limit: "50",
|
|
215
|
+
},
|
|
216
|
+
});
|
|
231
217
|
|
|
232
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
218
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
233
219
|
expect(result).toEqual({
|
|
234
220
|
count: 1,
|
|
235
221
|
limit: 50,
|
|
@@ -241,15 +227,17 @@ describe("Product Projection Query - Generic", () => {
|
|
|
241
227
|
|
|
242
228
|
test("Filter on valid slug", async () => {
|
|
243
229
|
{
|
|
244
|
-
const response = await
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
230
|
+
const response = await ctMock.app.inject({
|
|
231
|
+
method: "GET",
|
|
232
|
+
url: "/dummy/product-projections",
|
|
233
|
+
query: {
|
|
234
|
+
limit: "50",
|
|
235
|
+
where: "slug(nl-NL=:slug)",
|
|
249
236
|
"var.slug": "test-product",
|
|
250
|
-
}
|
|
237
|
+
},
|
|
238
|
+
});
|
|
251
239
|
|
|
252
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
240
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
253
241
|
expect(result).toEqual({
|
|
254
242
|
count: 1,
|
|
255
243
|
limit: 50,
|
|
@@ -262,18 +250,19 @@ describe("Product Projection Query - Generic", () => {
|
|
|
262
250
|
|
|
263
251
|
test("Filter on complex query", async () => {
|
|
264
252
|
{
|
|
265
|
-
const response = await
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
253
|
+
const response = await ctMock.app.inject({
|
|
254
|
+
method: "GET",
|
|
255
|
+
url: "/dummy/product-projections",
|
|
256
|
+
query: {
|
|
257
|
+
limit: "50",
|
|
258
|
+
where:
|
|
270
259
|
'slug(nl-NL=:slug) and variants(attributes(name="store" and value="test-store"))',
|
|
271
|
-
],
|
|
272
260
|
"var.slug": "test-product",
|
|
273
261
|
"var.store": "test-store",
|
|
274
|
-
}
|
|
262
|
+
},
|
|
263
|
+
});
|
|
275
264
|
|
|
276
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
265
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
277
266
|
expect(result).toEqual({
|
|
278
267
|
count: 1,
|
|
279
268
|
limit: 50,
|
|
@@ -286,15 +275,17 @@ describe("Product Projection Query - Generic", () => {
|
|
|
286
275
|
|
|
287
276
|
test("Filter on invalid slug", async () => {
|
|
288
277
|
{
|
|
289
|
-
const response = await
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
278
|
+
const response = await ctMock.app.inject({
|
|
279
|
+
method: "GET",
|
|
280
|
+
url: "/dummy/product-projections",
|
|
281
|
+
query: {
|
|
282
|
+
limit: "50",
|
|
283
|
+
where: "slug(nl-NL=:slug)",
|
|
294
284
|
"var.slug": "missing-product",
|
|
295
|
-
}
|
|
285
|
+
},
|
|
286
|
+
});
|
|
296
287
|
|
|
297
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
288
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
298
289
|
expect(result).toEqual({
|
|
299
290
|
count: 0,
|
|
300
291
|
limit: 50,
|
|
@@ -310,13 +301,15 @@ describe("Product Projection Query - Generic", () => {
|
|
|
310
301
|
describe("Product Projection Search - Generic", () => {
|
|
311
302
|
test("Pagination", async () => {
|
|
312
303
|
{
|
|
313
|
-
const response = await
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
304
|
+
const response = await ctMock.app.inject({
|
|
305
|
+
method: "GET",
|
|
306
|
+
url: "/dummy/product-projections/search",
|
|
307
|
+
query: {
|
|
308
|
+
limit: "50",
|
|
309
|
+
},
|
|
310
|
+
});
|
|
318
311
|
|
|
319
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
312
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
320
313
|
expect(result).toEqual({
|
|
321
314
|
count: 1,
|
|
322
315
|
limit: 50,
|
|
@@ -327,19 +320,21 @@ describe("Product Projection Search - Generic", () => {
|
|
|
327
320
|
});
|
|
328
321
|
}
|
|
329
322
|
{
|
|
330
|
-
const response = await
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
323
|
+
const response = await ctMock.app.inject({
|
|
324
|
+
method: "GET",
|
|
325
|
+
url: "/dummy/product-projections/search",
|
|
326
|
+
query: {
|
|
327
|
+
limit: "50",
|
|
328
|
+
offset: "50",
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
const projection: ProductProjection = response.json();
|
|
338
333
|
expect(projection).toEqual({
|
|
339
|
-
count:
|
|
334
|
+
count: 0,
|
|
340
335
|
limit: 50,
|
|
341
336
|
offset: 50,
|
|
342
|
-
total:
|
|
337
|
+
total: 1,
|
|
343
338
|
facets: {},
|
|
344
339
|
results: [],
|
|
345
340
|
});
|
|
@@ -348,14 +343,16 @@ describe("Product Projection Search - Generic", () => {
|
|
|
348
343
|
|
|
349
344
|
test("Search - unpublished", async () => {
|
|
350
345
|
{
|
|
351
|
-
const response = await
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
346
|
+
const response = await ctMock.app.inject({
|
|
347
|
+
method: "GET",
|
|
348
|
+
url: "/dummy/product-projections/search",
|
|
349
|
+
query: {
|
|
350
|
+
limit: "50",
|
|
351
|
+
staged: "true",
|
|
352
|
+
},
|
|
353
|
+
});
|
|
357
354
|
|
|
358
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
355
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
359
356
|
|
|
360
357
|
expect(result).toMatchObject({
|
|
361
358
|
count: 2,
|
|
@@ -372,25 +369,29 @@ describe("Product Projection Search - Generic", () => {
|
|
|
372
369
|
});
|
|
373
370
|
|
|
374
371
|
test("Get 404 when not found by key with expand", async () => {
|
|
375
|
-
const response = await
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
372
|
+
const response = await ctMock.app.inject({
|
|
373
|
+
method: "GET",
|
|
374
|
+
url: "/dummy/product-projections/key=DOESNOTEXIST",
|
|
375
|
+
query: {
|
|
376
|
+
expand: "categories[*]",
|
|
377
|
+
},
|
|
378
|
+
});
|
|
380
379
|
|
|
381
|
-
expect(response.
|
|
380
|
+
expect(response.statusCode).toBe(404);
|
|
382
381
|
});
|
|
383
382
|
});
|
|
384
383
|
|
|
385
384
|
describe("Product Projection Search - Filters", () => {
|
|
386
385
|
test("variants.sku", async () => {
|
|
387
|
-
const response = await
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
386
|
+
const response = await ctMock.app.inject({
|
|
387
|
+
method: "GET",
|
|
388
|
+
url: "/dummy/product-projections/search",
|
|
389
|
+
query: {
|
|
390
|
+
filter: 'variants.sku:"my-sku"',
|
|
391
|
+
},
|
|
392
|
+
});
|
|
392
393
|
|
|
393
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
394
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
394
395
|
expect(result).toMatchObject({
|
|
395
396
|
count: 1,
|
|
396
397
|
results: [
|
|
@@ -402,13 +403,15 @@ describe("Product Projection Search - Filters", () => {
|
|
|
402
403
|
});
|
|
403
404
|
|
|
404
405
|
test("variants.attributes.range - match", async () => {
|
|
405
|
-
const response = await
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
406
|
+
const response = await ctMock.app.inject({
|
|
407
|
+
method: "GET",
|
|
408
|
+
url: "/dummy/product-projections/search",
|
|
409
|
+
query: {
|
|
410
|
+
filter: "variants.attributes.number:range(0 TO 10)",
|
|
411
|
+
},
|
|
412
|
+
});
|
|
410
413
|
|
|
411
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
414
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
412
415
|
expect(result).toMatchObject({
|
|
413
416
|
count: 1,
|
|
414
417
|
results: [
|
|
@@ -420,13 +423,15 @@ describe("Product Projection Search - Filters", () => {
|
|
|
420
423
|
});
|
|
421
424
|
|
|
422
425
|
test("variants.attributes.range - mismatch", async () => {
|
|
423
|
-
const response = await
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
426
|
+
const response = await ctMock.app.inject({
|
|
427
|
+
method: "GET",
|
|
428
|
+
url: "/dummy/product-projections/search",
|
|
429
|
+
query: {
|
|
430
|
+
filter: "variants.attributes.number:range(5 TO 10)",
|
|
431
|
+
},
|
|
432
|
+
});
|
|
428
433
|
|
|
429
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
434
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
430
435
|
expect(result).toMatchObject({
|
|
431
436
|
count: 0,
|
|
432
437
|
results: [],
|
|
@@ -436,13 +441,15 @@ describe("Product Projection Search - Filters", () => {
|
|
|
436
441
|
|
|
437
442
|
describe("Product Projection Search - Facets", () => {
|
|
438
443
|
test("termExpr - variants.attributes.number", async () => {
|
|
439
|
-
const response = await
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
+
const response = await ctMock.app.inject({
|
|
445
|
+
method: "GET",
|
|
446
|
+
url: "/dummy/product-projections/search",
|
|
447
|
+
query: {
|
|
448
|
+
facet: "variants.attributes.number",
|
|
449
|
+
},
|
|
450
|
+
});
|
|
444
451
|
|
|
445
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
452
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
446
453
|
expect(result).toMatchObject({
|
|
447
454
|
count: 1,
|
|
448
455
|
facets: {
|
|
@@ -472,13 +479,15 @@ describe("Product Projection Search - Facets", () => {
|
|
|
472
479
|
});
|
|
473
480
|
|
|
474
481
|
test("filterExpr - variants.attributes.number", async () => {
|
|
475
|
-
const response = await
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
482
|
+
const response = await ctMock.app.inject({
|
|
483
|
+
method: "GET",
|
|
484
|
+
url: "/dummy/product-projections/search",
|
|
485
|
+
query: {
|
|
486
|
+
facet: "variants.attributes.number:3,4",
|
|
487
|
+
},
|
|
488
|
+
});
|
|
480
489
|
|
|
481
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
490
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
482
491
|
expect(result).toMatchObject({
|
|
483
492
|
count: 1,
|
|
484
493
|
facets: {
|
|
@@ -496,15 +505,16 @@ describe("Product Projection Search - Facets", () => {
|
|
|
496
505
|
});
|
|
497
506
|
|
|
498
507
|
test("rangeExpr - variants.attributes.number", async () => {
|
|
499
|
-
const response = await
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
508
|
+
const response = await ctMock.app.inject({
|
|
509
|
+
method: "GET",
|
|
510
|
+
url: "/dummy/product-projections/search",
|
|
511
|
+
query: {
|
|
512
|
+
facet:
|
|
503
513
|
"variants.attributes.number:range(* TO 5), (5 TO 25), (25 TO 100)",
|
|
504
|
-
|
|
505
|
-
|
|
514
|
+
},
|
|
515
|
+
});
|
|
506
516
|
|
|
507
|
-
const result: ProductProjectionPagedSearchResponse = response.
|
|
517
|
+
const result: ProductProjectionPagedSearchResponse = response.json();
|
|
508
518
|
expect(result).toMatchObject({
|
|
509
519
|
count: 1,
|
|
510
520
|
facets: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
|
2
2
|
import { queryParamsArray, queryParamsValue } from "../helpers.ts";
|
|
3
3
|
import { getRepositoryContext } from "../repositories/helpers.ts";
|
|
4
4
|
import type {
|
|
@@ -10,7 +10,10 @@ import AbstractService from "./abstract.ts";
|
|
|
10
10
|
export class ProductProjectionService extends AbstractService {
|
|
11
11
|
public repository: ProductProjectionRepository;
|
|
12
12
|
|
|
13
|
-
constructor(
|
|
13
|
+
constructor(
|
|
14
|
+
parent: FastifyInstance,
|
|
15
|
+
repository: ProductProjectionRepository,
|
|
16
|
+
) {
|
|
14
17
|
super(parent);
|
|
15
18
|
this.repository = repository;
|
|
16
19
|
}
|
|
@@ -19,25 +22,38 @@ export class ProductProjectionService extends AbstractService {
|
|
|
19
22
|
return "product-projections";
|
|
20
23
|
}
|
|
21
24
|
|
|
22
|
-
extraRoutes(
|
|
23
|
-
|
|
25
|
+
extraRoutes(instance: FastifyInstance) {
|
|
26
|
+
instance.get("/search", this.search.bind(this));
|
|
24
27
|
}
|
|
25
28
|
|
|
26
|
-
get(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
async get(
|
|
30
|
+
request: FastifyRequest<{
|
|
31
|
+
Params: Record<string, string>;
|
|
32
|
+
Querystring: Record<string, any>;
|
|
33
|
+
}>,
|
|
34
|
+
reply: FastifyReply,
|
|
35
|
+
) {
|
|
36
|
+
const query = request.query;
|
|
37
|
+
const limit = this._parseParam(query.limit);
|
|
38
|
+
const offset = this._parseParam(query.offset);
|
|
29
39
|
|
|
30
|
-
const result = this.repository.query(getRepositoryContext(request), {
|
|
31
|
-
...
|
|
32
|
-
expand: this._parseParam(
|
|
33
|
-
where: this._parseParam(
|
|
40
|
+
const result = await this.repository.query(getRepositoryContext(request), {
|
|
41
|
+
...query,
|
|
42
|
+
expand: this._parseParam(query.expand),
|
|
43
|
+
where: this._parseParam(query.where),
|
|
34
44
|
limit: limit !== undefined ? Number(limit) : undefined,
|
|
35
45
|
offset: offset !== undefined ? Number(offset) : undefined,
|
|
36
46
|
});
|
|
37
|
-
|
|
47
|
+
return reply.status(200).send(result);
|
|
38
48
|
}
|
|
39
49
|
|
|
40
|
-
search(
|
|
50
|
+
async search(
|
|
51
|
+
request: FastifyRequest<{
|
|
52
|
+
Params: Record<string, string>;
|
|
53
|
+
Querystring: Record<string, any>;
|
|
54
|
+
}>,
|
|
55
|
+
reply: FastifyReply,
|
|
56
|
+
) {
|
|
41
57
|
const query = request.query;
|
|
42
58
|
const searchParams: ProductProjectionQueryParams = {
|
|
43
59
|
filter: queryParamsArray(query.filter),
|
|
@@ -54,10 +70,10 @@ export class ProductProjectionService extends AbstractService {
|
|
|
54
70
|
offset: query.offset ? Number(queryParamsValue(query.offset)) : undefined,
|
|
55
71
|
limit: query.limit ? Number(queryParamsValue(query.limit)) : undefined,
|
|
56
72
|
};
|
|
57
|
-
const resource = this.repository.search(
|
|
73
|
+
const resource = await this.repository.search(
|
|
58
74
|
getRepositoryContext(request),
|
|
59
75
|
searchParams,
|
|
60
76
|
);
|
|
61
|
-
|
|
77
|
+
return reply.status(200).send(resource);
|
|
62
78
|
}
|
|
63
79
|
}
|
|
@@ -1,28 +1,36 @@
|
|
|
1
|
-
import type { ProductSelectionDraft } from "@commercetools/platform-sdk";
|
|
2
|
-
import supertest from "supertest";
|
|
3
1
|
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { productSelectionDraftFactory } from "#src/testing/index.ts";
|
|
4
3
|
import { CommercetoolsMock } from "../index.ts";
|
|
5
4
|
|
|
6
5
|
const ctMock = new CommercetoolsMock();
|
|
7
6
|
|
|
8
7
|
describe("product-selection", () => {
|
|
8
|
+
const productSelectionDraft = productSelectionDraftFactory(ctMock);
|
|
9
|
+
|
|
9
10
|
test("Create product selection", async () => {
|
|
10
|
-
const draft
|
|
11
|
+
const draft = productSelectionDraft.build({
|
|
11
12
|
name: {
|
|
12
13
|
en: "foo",
|
|
13
14
|
},
|
|
14
15
|
key: "foo",
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const response = await ctMock.app.inject({
|
|
19
|
+
method: "POST",
|
|
20
|
+
url: "/dummy/product-selections",
|
|
21
|
+
payload: draft,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(response.statusCode).toBe(201);
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
const productSelection = response.json();
|
|
21
27
|
|
|
22
|
-
expect(
|
|
28
|
+
expect(productSelection).toEqual({
|
|
23
29
|
createdAt: expect.anything(),
|
|
30
|
+
createdBy: expect.anything(),
|
|
24
31
|
id: expect.anything(),
|
|
25
32
|
lastModifiedAt: expect.anything(),
|
|
33
|
+
lastModifiedBy: expect.anything(),
|
|
26
34
|
name: {
|
|
27
35
|
en: "foo",
|
|
28
36
|
},
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FastifyInstance } from "fastify";
|
|
2
2
|
import type { ProductSelectionRepository } from "../repositories/product-selection.ts";
|
|
3
3
|
import AbstractService from "./abstract.ts";
|
|
4
4
|
|
|
5
5
|
export class ProductSelectionService extends AbstractService {
|
|
6
6
|
public repository: ProductSelectionRepository;
|
|
7
7
|
|
|
8
|
-
constructor(parent:
|
|
8
|
+
constructor(parent: FastifyInstance, repository: ProductSelectionRepository) {
|
|
9
9
|
super(parent);
|
|
10
10
|
this.repository = repository;
|
|
11
11
|
}
|