@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.
Files changed (281) hide show
  1. package/README.md +31 -8
  2. package/dist/abstract-BKFcva6S.mjs +1044 -0
  3. package/dist/abstract-BKFcva6S.mjs.map +1 -0
  4. package/dist/config-BcNSzPZz.d.mts +1718 -0
  5. package/dist/index.d.mts +50 -1633
  6. package/dist/index.mjs +3769 -2653
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/storage/sqlite.d.mts +59 -0
  9. package/dist/storage/sqlite.mjs +234 -0
  10. package/dist/storage/sqlite.mjs.map +1 -0
  11. package/package.json +26 -29
  12. package/src/ctMock.ts +125 -136
  13. package/src/helpers.ts +14 -6
  14. package/src/index.ts +5 -0
  15. package/src/lib/masking.ts +4 -5
  16. package/src/lib/product-review-statistics.test.ts +257 -294
  17. package/src/lib/review-statistics.ts +17 -4
  18. package/src/oauth/helpers.ts +7 -4
  19. package/src/oauth/server.test.ts +102 -62
  20. package/src/oauth/server.ts +215 -213
  21. package/src/oauth/store.ts +20 -6
  22. package/src/orderSearch.ts +3 -3
  23. package/src/product-projection-search.ts +38 -20
  24. package/src/product-search-availability.test.ts +31 -52
  25. package/src/product-search.ts +19 -10
  26. package/src/projectAPI.ts +6 -22
  27. package/src/repositories/abstract.ts +182 -48
  28. package/src/repositories/as-associate.test.ts +19 -19
  29. package/src/repositories/associate-role.ts +12 -23
  30. package/src/repositories/attribute-group.test.ts +23 -23
  31. package/src/repositories/attribute-group.ts +6 -4
  32. package/src/repositories/business-unit.test.ts +63 -57
  33. package/src/repositories/business-unit.ts +107 -55
  34. package/src/repositories/cart/actions.ts +96 -65
  35. package/src/repositories/cart/helpers.ts +15 -11
  36. package/src/repositories/cart/index.test.ts +136 -30
  37. package/src/repositories/cart/index.ts +76 -59
  38. package/src/repositories/cart-discount/actions.ts +12 -44
  39. package/src/repositories/cart-discount/index.ts +20 -8
  40. package/src/repositories/category/actions.ts +27 -27
  41. package/src/repositories/category/index.test.ts +13 -9
  42. package/src/repositories/category/index.ts +40 -23
  43. package/src/repositories/channel.test.ts +53 -51
  44. package/src/repositories/channel.ts +12 -22
  45. package/src/repositories/custom-object.ts +34 -25
  46. package/src/repositories/customer/actions.ts +47 -25
  47. package/src/repositories/customer/index.test.ts +11 -11
  48. package/src/repositories/customer/index.ts +65 -35
  49. package/src/repositories/customer-group.test.ts +44 -42
  50. package/src/repositories/customer-group.ts +12 -22
  51. package/src/repositories/discount-code/actions.ts +3 -19
  52. package/src/repositories/discount-code/index.ts +9 -4
  53. package/src/repositories/discount-group/index.ts +8 -3
  54. package/src/repositories/extension.test.ts +27 -27
  55. package/src/repositories/extension.ts +10 -5
  56. package/src/repositories/helpers.ts +126 -47
  57. package/src/repositories/inventory-entry/actions.ts +3 -24
  58. package/src/repositories/inventory-entry/index.ts +19 -11
  59. package/src/repositories/my-customer.ts +13 -12
  60. package/src/repositories/my-order.ts +5 -2
  61. package/src/repositories/order/actions.ts +84 -56
  62. package/src/repositories/order/index.test.ts +36 -31
  63. package/src/repositories/order/index.ts +83 -49
  64. package/src/repositories/order-edit.ts +8 -3
  65. package/src/repositories/payment/actions.ts +64 -44
  66. package/src/repositories/payment/helpers.ts +3 -3
  67. package/src/repositories/payment/index.ts +28 -12
  68. package/src/repositories/product/actions.ts +133 -98
  69. package/src/repositories/product/helpers.ts +29 -16
  70. package/src/repositories/product/index.ts +42 -25
  71. package/src/repositories/product-discount.ts +6 -4
  72. package/src/repositories/product-projection.ts +41 -21
  73. package/src/repositories/product-selection.ts +8 -15
  74. package/src/repositories/product-tailoring.ts +22 -3
  75. package/src/repositories/product-type.ts +45 -4
  76. package/src/repositories/project.ts +57 -13
  77. package/src/repositories/quote/actions.ts +5 -28
  78. package/src/repositories/quote/index.ts +29 -6
  79. package/src/repositories/quote-request/actions.ts +5 -28
  80. package/src/repositories/quote-request/index.test.ts +3 -3
  81. package/src/repositories/quote-request/index.ts +31 -11
  82. package/src/repositories/quote-staged/actions.ts +5 -28
  83. package/src/repositories/quote-staged/index.ts +22 -8
  84. package/src/repositories/recurrence-policy/index.ts +6 -4
  85. package/src/repositories/recurring-order/actions.ts +7 -32
  86. package/src/repositories/recurring-order/index.ts +8 -6
  87. package/src/repositories/review.test.ts +147 -142
  88. package/src/repositories/review.ts +31 -37
  89. package/src/repositories/shipping-method/actions.ts +11 -28
  90. package/src/repositories/shipping-method/index.ts +26 -15
  91. package/src/repositories/shopping-list/actions.ts +21 -31
  92. package/src/repositories/shopping-list/index.ts +44 -22
  93. package/src/repositories/standalone-price.ts +6 -4
  94. package/src/repositories/state.ts +15 -9
  95. package/src/repositories/store.ts +21 -32
  96. package/src/repositories/subscription.test.ts +22 -22
  97. package/src/repositories/subscription.ts +8 -3
  98. package/src/repositories/tax-category/index.ts +8 -3
  99. package/src/repositories/type/actions.ts +21 -3
  100. package/src/repositories/type/index.ts +5 -3
  101. package/src/repositories/zone.test.ts +112 -77
  102. package/src/repositories/zone.ts +5 -3
  103. package/src/schemas/generated/associate-role.ts +13 -0
  104. package/src/schemas/generated/attribute-group.ts +12 -0
  105. package/src/schemas/generated/business-unit.ts +38 -0
  106. package/src/schemas/generated/cart-discount.ts +33 -0
  107. package/src/schemas/generated/cart.ts +61 -0
  108. package/src/schemas/generated/category.ts +25 -0
  109. package/src/schemas/generated/channel.ts +21 -0
  110. package/src/schemas/generated/common.ts +1372 -0
  111. package/src/schemas/generated/custom-object.ts +11 -0
  112. package/src/schemas/generated/customer-group.ts +11 -0
  113. package/src/schemas/generated/customer.ts +47 -0
  114. package/src/schemas/generated/discount-code.ts +25 -0
  115. package/src/schemas/generated/discount-group.ts +13 -0
  116. package/src/schemas/generated/extension.ts +15 -0
  117. package/src/schemas/generated/index.ts +42 -0
  118. package/src/schemas/generated/inventory-entry.ts +20 -0
  119. package/src/schemas/generated/my-quote-request.ts +10 -0
  120. package/src/schemas/generated/order-edit.ts +18 -0
  121. package/src/schemas/generated/order-from-cart.ts +25 -0
  122. package/src/schemas/generated/payment.ts +30 -0
  123. package/src/schemas/generated/product-discount.ts +20 -0
  124. package/src/schemas/generated/product-selection.ts +18 -0
  125. package/src/schemas/generated/product-tailoring.ts +26 -0
  126. package/src/schemas/generated/product-type.ts +12 -0
  127. package/src/schemas/generated/product.ts +37 -0
  128. package/src/schemas/generated/quote-request.ts +19 -0
  129. package/src/schemas/generated/quote.ts +18 -0
  130. package/src/schemas/generated/recurrence-policy.ts +15 -0
  131. package/src/schemas/generated/recurring-order.ts +19 -0
  132. package/src/schemas/generated/review.ts +24 -0
  133. package/src/schemas/generated/shipping-method.ts +24 -0
  134. package/src/schemas/generated/shopping-list.ts +28 -0
  135. package/src/schemas/generated/staged-quote.ts +18 -0
  136. package/src/schemas/generated/standalone-price.ts +32 -0
  137. package/src/schemas/generated/state.ts +20 -0
  138. package/src/schemas/generated/store.ts +23 -0
  139. package/src/schemas/generated/subscription.ts +20 -0
  140. package/src/schemas/generated/tax-category.ts +12 -0
  141. package/src/schemas/generated/type.ts +17 -0
  142. package/src/schemas/generated/zone.ts +12 -0
  143. package/src/schemas/update-request.ts +3 -5
  144. package/src/server.ts +32 -4
  145. package/src/services/abstract.ts +207 -101
  146. package/src/services/as-associate-cart.test.ts +28 -36
  147. package/src/services/as-associate-cart.ts +15 -12
  148. package/src/services/as-associate-order.test.ts +33 -40
  149. package/src/services/as-associate-order.ts +15 -12
  150. package/src/services/as-associate-quote-request.ts +15 -12
  151. package/src/services/as-associate-shopping-list.test.ts +25 -35
  152. package/src/services/as-associate-shopping-list.ts +15 -12
  153. package/src/services/as-associate.test.ts +21 -15
  154. package/src/services/as-associate.ts +23 -22
  155. package/src/services/associate-roles.test.ts +16 -22
  156. package/src/services/associate-roles.ts +2 -2
  157. package/src/services/attribute-group.test.ts +40 -44
  158. package/src/services/attribute-group.ts +2 -2
  159. package/src/services/business-units.test.ts +227 -163
  160. package/src/services/business-units.ts +2 -2
  161. package/src/services/cart-discount.test.ts +253 -187
  162. package/src/services/cart-discount.ts +2 -2
  163. package/src/services/cart.test.ts +833 -832
  164. package/src/services/cart.ts +31 -12
  165. package/src/services/category.test.ts +208 -130
  166. package/src/services/category.ts +2 -2
  167. package/src/services/channel.test.ts +39 -44
  168. package/src/services/channel.ts +2 -2
  169. package/src/services/custom-object.test.ts +103 -79
  170. package/src/services/custom-object.ts +106 -38
  171. package/src/services/customer-group.test.ts +39 -44
  172. package/src/services/customer-group.ts +2 -2
  173. package/src/services/customer.test.ts +357 -292
  174. package/src/services/customer.ts +70 -23
  175. package/src/services/discount-code.test.ts +57 -68
  176. package/src/services/discount-code.ts +2 -2
  177. package/src/services/discount-group.test.ts +111 -134
  178. package/src/services/discount-group.ts +2 -2
  179. package/src/services/draft-validation.test.ts +255 -0
  180. package/src/services/extension.test.ts +39 -44
  181. package/src/services/extension.ts +2 -2
  182. package/src/services/inventory-entry.test.ts +106 -87
  183. package/src/services/inventory-entry.ts +2 -2
  184. package/src/services/my-business-unit.test.ts +82 -112
  185. package/src/services/my-business-unit.ts +25 -19
  186. package/src/services/my-cart.test.ts +46 -41
  187. package/src/services/my-cart.ts +32 -28
  188. package/src/services/my-customer.test.ts +153 -88
  189. package/src/services/my-customer.ts +130 -61
  190. package/src/services/my-order.ts +15 -12
  191. package/src/services/my-payment.test.ts +30 -24
  192. package/src/services/my-payment.ts +2 -2
  193. package/src/services/my-shopping-list.ts +2 -2
  194. package/src/services/order.test.ts +332 -276
  195. package/src/services/order.ts +45 -27
  196. package/src/services/payment.test.ts +31 -29
  197. package/src/services/payment.ts +2 -2
  198. package/src/services/product-discount.test.ts +39 -46
  199. package/src/services/product-discount.ts +2 -2
  200. package/src/services/product-projection.test.ts +176 -166
  201. package/src/services/product-projection.ts +31 -15
  202. package/src/services/product-selection.test.ts +17 -9
  203. package/src/services/product-selection.ts +2 -2
  204. package/src/services/product-type.test.ts +80 -21
  205. package/src/services/product-type.ts +2 -2
  206. package/src/services/product.test.ts +569 -534
  207. package/src/services/product.ts +14 -7
  208. package/src/services/project.test.ts +22 -12
  209. package/src/services/project.ts +28 -13
  210. package/src/services/quote-request.test.ts +36 -39
  211. package/src/services/quote-request.ts +2 -2
  212. package/src/services/quote-staged.ts +2 -2
  213. package/src/services/quote.ts +2 -2
  214. package/src/services/recurrence-policy.test.ts +114 -139
  215. package/src/services/recurrence-policy.ts +2 -2
  216. package/src/services/recurring-order.test.ts +149 -194
  217. package/src/services/recurring-order.ts +2 -2
  218. package/src/services/reviews.test.ts +127 -106
  219. package/src/services/reviews.ts +2 -2
  220. package/src/services/shipping-method.test.ts +96 -125
  221. package/src/services/shipping-method.ts +24 -12
  222. package/src/services/shopping-list.test.ts +183 -141
  223. package/src/services/shopping-list.ts +2 -2
  224. package/src/services/standalone-price.test.ts +60 -46
  225. package/src/services/standalone-price.ts +2 -2
  226. package/src/services/state.test.ts +20 -25
  227. package/src/services/state.ts +2 -2
  228. package/src/services/store.test.ts +26 -45
  229. package/src/services/store.ts +2 -2
  230. package/src/services/subscription.test.ts +39 -44
  231. package/src/services/subscription.ts +2 -2
  232. package/src/services/tax-category.test.ts +33 -36
  233. package/src/services/tax-category.ts +2 -2
  234. package/src/services/type.test.ts +45 -44
  235. package/src/services/type.ts +2 -2
  236. package/src/services/zone.test.ts +40 -44
  237. package/src/services/zone.ts +2 -2
  238. package/src/shipping.ts +41 -11
  239. package/src/storage/abstract.ts +248 -17
  240. package/src/storage/in-memory.ts +147 -290
  241. package/src/storage/sqlite.ts +429 -0
  242. package/src/storage/storage-map.ts +75 -0
  243. package/src/storage/storage.test-helpers.ts +97 -0
  244. package/src/storage/storage.test.ts +802 -0
  245. package/src/testing/associate-role.ts +28 -0
  246. package/src/testing/attribute-group.ts +27 -0
  247. package/src/testing/business-unit.ts +9 -8
  248. package/src/testing/cart-discount.ts +34 -0
  249. package/src/testing/cart.ts +20 -0
  250. package/src/testing/category.ts +25 -0
  251. package/src/testing/channel.ts +23 -0
  252. package/src/testing/custom-object.ts +27 -0
  253. package/src/testing/customer-group.ts +26 -0
  254. package/src/testing/customer.ts +36 -33
  255. package/src/testing/discount-code.ts +29 -0
  256. package/src/testing/discount-group.ts +27 -0
  257. package/src/testing/extension.ts +32 -0
  258. package/src/testing/index.ts +33 -0
  259. package/src/testing/inventory-entry.ts +26 -0
  260. package/src/testing/order.ts +27 -0
  261. package/src/testing/payment.ts +23 -0
  262. package/src/testing/product-discount.ts +33 -0
  263. package/src/testing/product-selection.ts +28 -0
  264. package/src/testing/product-type.ts +27 -0
  265. package/src/testing/product.ts +38 -0
  266. package/src/testing/quote-request.ts +29 -0
  267. package/src/testing/recurrence-policy.ts +33 -0
  268. package/src/testing/recurring-order.ts +32 -0
  269. package/src/testing/review.ts +24 -0
  270. package/src/testing/shipping-method.ts +31 -0
  271. package/src/testing/shopping-list.ts +25 -0
  272. package/src/testing/standalone-price.ts +31 -0
  273. package/src/testing/state.ts +21 -0
  274. package/src/testing/store.ts +26 -0
  275. package/src/testing/subscription.ts +38 -0
  276. package/src/testing/tax-category.ts +27 -0
  277. package/src/testing/type.ts +9 -6
  278. package/src/testing/zone.ts +22 -0
  279. package/src/validate.test.ts +122 -0
  280. package/src/validate.ts +78 -7
  281. 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
- const draft: ProductTypeDraft = {
28
- name: "Default Product Type",
29
- description: "Product type for testing",
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
- const productDraft: Writable<ProductDraft> = {
42
- publish: false,
43
- key: "my-unpublished-product",
44
- attributes: [{ name: "number", value: 11 as any }],
45
- masterVariant: {
46
- sku: "my-unpub-sku",
47
- prices: [
48
- {
49
- value: {
50
- currencyCode: "EUR",
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
- name: {
63
- "nl-NL": "test unpublished product",
64
- },
65
- productType: {
66
- typeId: "product-type",
67
- id: productType.id,
68
- },
69
- slug: {
70
- "nl-NL": "test-unpublished-product",
71
- },
72
- };
73
-
74
- const response = await supertest(ctMock.app)
75
- .post("/dummy/products")
76
- .send(productDraft);
77
- expect(response.ok).toBe(true);
78
- unpublishedProduct = response.body;
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: Writable<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 response = await supertest(ctMock.app)
140
- .post("/dummy/products")
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: productDraft.name,
195
- slug: productDraft.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 supertest(ctMock.app).get(
213
- `/dummy/product-projections/${publishedProduct.id}`,
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.body;
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 supertest(ctMock.app)
227
- .get("/dummy/product-projections")
228
- .query({
229
- limit: 50,
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.body;
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 supertest(ctMock.app)
245
- .get("/dummy/product-projections")
246
- .query({
247
- limit: 50,
248
- where: ["slug(nl-NL=:slug)"],
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.body;
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 supertest(ctMock.app)
266
- .get("/dummy/product-projections")
267
- .query({
268
- limit: 50,
269
- where: [
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.body;
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 supertest(ctMock.app)
290
- .get("/dummy/product-projections")
291
- .query({
292
- limit: 50,
293
- where: ["slug(nl-NL=:slug)"],
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.body;
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 supertest(ctMock.app)
314
- .get("/dummy/product-projections/search")
315
- .query({
316
- limit: 50,
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.body;
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 supertest(ctMock.app)
331
- .get("/dummy/product-projections/search")
332
- .query({
333
- limit: 50,
334
- offset: 50,
335
- });
336
-
337
- const projection: ProductProjection = response.body;
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: 1,
334
+ count: 0,
340
335
  limit: 50,
341
336
  offset: 50,
342
- total: 0,
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 supertest(ctMock.app)
352
- .get("/dummy/product-projections/search")
353
- .query({
354
- limit: 50,
355
- staged: true,
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.body;
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 supertest(ctMock.app)
376
- .get("/dummy/product-projections/key=DOESNOTEXIST")
377
- .query({
378
- expand: ["categories[*]"],
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.status).toBe(404);
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 supertest(ctMock.app)
388
- .get("/dummy/product-projections/search")
389
- .query({
390
- filter: ['variants.sku:"my-sku"'],
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.body;
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 supertest(ctMock.app)
406
- .get("/dummy/product-projections/search")
407
- .query({
408
- filter: ["variants.attributes.number:range(0 TO 10)"],
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.body;
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 supertest(ctMock.app)
424
- .get("/dummy/product-projections/search")
425
- .query({
426
- filter: ["variants.attributes.number:range(5 TO 10)"],
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.body;
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 supertest(ctMock.app)
440
- .get("/dummy/product-projections/search")
441
- .query({
442
- facet: ["variants.attributes.number"],
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.body;
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 supertest(ctMock.app)
476
- .get("/dummy/product-projections/search")
477
- .query({
478
- facet: ["variants.attributes.number:3,4"],
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.body;
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 supertest(ctMock.app)
500
- .get("/dummy/product-projections/search")
501
- .query({
502
- facet: [
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.body;
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 { Request, Response, Router } from "express";
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(parent: Router, repository: ProductProjectionRepository) {
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(router: Router) {
23
- router.get("/search", this.search.bind(this));
25
+ extraRoutes(instance: FastifyInstance) {
26
+ instance.get("/search", this.search.bind(this));
24
27
  }
25
28
 
26
- get(request: Request, response: Response) {
27
- const limit = this._parseParam(request.query.limit);
28
- const offset = this._parseParam(request.query.offset);
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
- ...request.query,
32
- expand: this._parseParam(request.query.expand),
33
- where: this._parseParam(request.query.where),
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
- response.status(200).send(result);
47
+ return reply.status(200).send(result);
38
48
  }
39
49
 
40
- search(request: Request, response: Response) {
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
- response.status(200).send(resource);
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: ProductSelectionDraft = {
11
+ const draft = productSelectionDraft.build({
11
12
  name: {
12
13
  en: "foo",
13
14
  },
14
15
  key: "foo",
15
- };
16
- const response = await supertest(ctMock.app)
17
- .post("/dummy/product-selections")
18
- .send(draft);
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
- expect(response.status).toBe(201);
26
+ const productSelection = response.json();
21
27
 
22
- expect(response.body).toEqual({
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 { Router } from "express";
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: Router, repository: ProductSelectionRepository) {
8
+ constructor(parent: FastifyInstance, repository: ProductSelectionRepository) {
9
9
  super(parent);
10
10
  this.repository = repository;
11
11
  }