@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
@@ -12,7 +12,7 @@ import type {
12
12
  ReviewSetTitleAction,
13
13
  ReviewTransitionStateAction,
14
14
  } from "@commercetools/platform-sdk";
15
- import { describe, expect, test } from "vitest";
15
+ import { beforeAll, describe, expect, test } from "vitest";
16
16
  import type { Config } from "#src/config.ts";
17
17
  import { getBaseResourceProperties } from "#src/helpers.ts";
18
18
  import { InMemoryStorage } from "#src/storage/index.ts";
@@ -24,102 +24,107 @@ describe("Review Repository", () => {
24
24
  const repository = new ReviewRepository(config);
25
25
 
26
26
  // Add required dependencies for testing
27
- storage.add("dummy", "product", {
28
- ...getBaseResourceProperties(),
29
- id: "product-123",
30
- key: "test-product",
31
- productType: {
32
- typeId: "product-type",
33
- id: "product-type-123",
34
- },
35
- masterData: {
36
- current: {
37
- name: { "en-US": "Test Product" },
38
- slug: { "en-US": "test-product" },
39
- attributes: [],
40
- categories: [],
41
- masterVariant: {
42
- id: 1,
43
- sku: "test-sku",
44
- prices: [],
45
- },
46
- variants: [],
47
- searchKeywords: {},
27
+ beforeAll(async () => {
28
+ await storage.add("dummy", "product", {
29
+ ...getBaseResourceProperties(),
30
+ id: "product-123",
31
+ key: "test-product",
32
+ productType: {
33
+ typeId: "product-type",
34
+ id: "product-type-123",
48
35
  },
49
- published: true,
50
- staged: {
51
- name: { "en-US": "Test Product" },
52
- slug: { "en-US": "test-product" },
53
- attributes: [],
54
- categories: [],
55
- masterVariant: {
56
- id: 1,
57
- sku: "test-sku",
58
- prices: [],
36
+ masterData: {
37
+ current: {
38
+ name: { "en-US": "Test Product" },
39
+ slug: { "en-US": "test-product" },
40
+ attributes: [],
41
+ categories: [],
42
+ masterVariant: {
43
+ id: 1,
44
+ sku: "test-sku",
45
+ prices: [],
46
+ },
47
+ variants: [],
48
+ searchKeywords: {},
59
49
  },
60
- variants: [],
61
- searchKeywords: {},
62
- },
63
- hasStagedChanges: false,
64
- },
65
- });
66
-
67
- storage.add("dummy", "channel", {
68
- ...getBaseResourceProperties(),
69
- id: "channel-123",
70
- key: "test-channel",
71
- name: { "en-US": "Test Channel" },
72
- roles: ["ProductDistribution"],
73
- });
74
-
75
- storage.add("dummy", "customer", {
76
- ...getBaseResourceProperties(),
77
- id: "customer-123",
78
- email: "test@example.com",
79
- firstName: "John",
80
- lastName: "Doe",
81
- password: "hashed-password",
82
- addresses: [],
83
- defaultShippingAddressId: "",
84
- defaultBillingAddressId: "",
85
- customerNumber: "",
86
- externalId: "",
87
- key: "",
88
- stores: [],
89
- authenticationMode: "Password" as const,
90
- isEmailVerified: false,
91
- });
92
-
93
- storage.add("dummy", "state", {
94
- ...getBaseResourceProperties(),
95
- id: "state-123",
96
- key: "approved",
97
- type: "ReviewState",
98
- name: { "en-US": "Approved" },
99
- roles: ["ReviewIncludedInStatistics"],
100
- transitions: [],
101
- initial: false,
102
- builtIn: false,
103
- });
104
-
105
- storage.add("dummy", "type", {
106
- ...getBaseResourceProperties(),
107
- id: "type-123",
108
- key: "review-type",
109
- name: { "en-US": "Review Type" },
110
- resourceTypeIds: ["review"],
111
- fieldDefinitions: [
112
- {
113
- name: "helpfulVotes",
114
- label: { "en-US": "Helpful Votes" },
115
- required: false,
116
- type: { name: "Number" },
117
- inputHint: "SingleLine",
50
+ published: true,
51
+ staged: {
52
+ name: { "en-US": "Test Product" },
53
+ slug: { "en-US": "test-product" },
54
+ attributes: [],
55
+ categories: [],
56
+ masterVariant: {
57
+ id: 1,
58
+ sku: "test-sku",
59
+ prices: [],
60
+ },
61
+ variants: [],
62
+ searchKeywords: {},
63
+ },
64
+ hasStagedChanges: false,
118
65
  },
119
- ],
66
+ });
67
+
68
+ await storage.add("dummy", "channel", {
69
+ ...getBaseResourceProperties(),
70
+ id: "channel-123",
71
+ key: "test-channel",
72
+ name: { "en-US": "Test Channel" },
73
+ roles: ["ProductDistribution"],
74
+ });
75
+
76
+ await storage.add("dummy", "customer", {
77
+ ...getBaseResourceProperties(),
78
+ id: "customer-123",
79
+ email: "test@example.com",
80
+ firstName: "John",
81
+ lastName: "Doe",
82
+ password: "hashed-password",
83
+ addresses: [],
84
+ defaultShippingAddressId: "",
85
+ defaultBillingAddressId: "",
86
+ customerNumber: "",
87
+ externalId: "",
88
+ key: "",
89
+ stores: [],
90
+ authenticationMode: "Password" as const,
91
+ isEmailVerified: false,
92
+ shippingAddressIds: [],
93
+ billingAddressIds: [],
94
+ customerGroupAssignments: [],
95
+ });
96
+
97
+ await storage.add("dummy", "state", {
98
+ ...getBaseResourceProperties(),
99
+ id: "state-123",
100
+ key: "approved",
101
+ type: "ReviewState",
102
+ name: { "en-US": "Approved" },
103
+ roles: ["ReviewIncludedInStatistics"],
104
+ transitions: [],
105
+ initial: false,
106
+ builtIn: false,
107
+ });
108
+
109
+ await storage.add("dummy", "type", {
110
+ ...getBaseResourceProperties(),
111
+ id: "type-123",
112
+ key: "review-type",
113
+ name: { "en-US": "Review Type" },
114
+ resourceTypeIds: ["review"],
115
+ fieldDefinitions: [
116
+ {
117
+ name: "helpfulVotes",
118
+ label: { "en-US": "Helpful Votes" },
119
+ required: false,
120
+ type: { name: "Number" },
121
+ inputHint: "SingleLine",
122
+ },
123
+ ],
124
+ });
120
125
  });
121
126
 
122
- test("create review with product target", () => {
127
+ test("create review with product target", async () => {
123
128
  const draft: ReviewDraft = {
124
129
  key: "product-review-1",
125
130
  authorName: "John Doe",
@@ -133,7 +138,7 @@ describe("Review Repository", () => {
133
138
  };
134
139
 
135
140
  const ctx = { projectKey: "dummy" };
136
- const result = repository.create(ctx, draft);
141
+ const result = await repository.create(ctx, draft);
137
142
 
138
143
  expect(result.id).toBeDefined();
139
144
  expect(result.version).toBe(1);
@@ -147,12 +152,12 @@ describe("Review Repository", () => {
147
152
  expect(result.includedInStatistics).toBe(true);
148
153
 
149
154
  // Test that the review is stored
150
- const items = repository.query(ctx);
155
+ const items = await repository.query(ctx);
151
156
  expect(items.count).toBe(1);
152
157
  expect(items.results[0].id).toBe(result.id);
153
158
  });
154
159
 
155
- test("create review with channel target", () => {
160
+ test("create review with channel target", async () => {
156
161
  const draft: ReviewDraft = {
157
162
  key: "channel-review-1",
158
163
  authorName: "Jane Smith",
@@ -166,14 +171,14 @@ describe("Review Repository", () => {
166
171
  };
167
172
 
168
173
  const ctx = { projectKey: "dummy" };
169
- const result = repository.create(ctx, draft);
174
+ const result = await repository.create(ctx, draft);
170
175
 
171
176
  expect(result.id).toBeDefined();
172
177
  expect(result.target?.typeId).toBe("channel");
173
178
  expect(result.target?.id).toBe("channel-123");
174
179
  });
175
180
 
176
- test("create review with all optional fields", () => {
181
+ test("create review with all optional fields", async () => {
177
182
  const draft: ReviewDraft = {
178
183
  key: "full-review",
179
184
  authorName: "Alice Johnson",
@@ -202,7 +207,7 @@ describe("Review Repository", () => {
202
207
  };
203
208
 
204
209
  const ctx = { projectKey: "dummy" };
205
- const result = repository.create(ctx, draft);
210
+ const result = await repository.create(ctx, draft);
206
211
 
207
212
  expect(result.id).toBeDefined();
208
213
  expect(result.locale).toBe(draft.locale);
@@ -211,7 +216,7 @@ describe("Review Repository", () => {
211
216
  expect(result.custom?.fields.helpfulVotes).toBe(10);
212
217
  });
213
218
 
214
- test("create review fails without target", () => {
219
+ test("create review fails without target", async () => {
215
220
  const draft: ReviewDraft = {
216
221
  authorName: "Bob Wilson",
217
222
  title: "No target review",
@@ -221,12 +226,12 @@ describe("Review Repository", () => {
221
226
 
222
227
  const ctx = { projectKey: "dummy" };
223
228
 
224
- expect(() => {
225
- repository.create(ctx, draft);
226
- }).toThrow("Missing target");
229
+ await expect(repository.create(ctx, draft)).rejects.toThrow(
230
+ "Missing target",
231
+ );
227
232
  });
228
233
 
229
- test("update review - setAuthorName", () => {
234
+ test("update review - setAuthorName", async () => {
230
235
  const draft: ReviewDraft = {
231
236
  authorName: "Original Author",
232
237
  title: "Test Review",
@@ -238,9 +243,9 @@ describe("Review Repository", () => {
238
243
  };
239
244
 
240
245
  const ctx = { projectKey: "dummy" };
241
- const review = repository.create(ctx, draft);
246
+ const review = await repository.create(ctx, draft);
242
247
 
243
- const result = repository.processUpdateActions(
248
+ const result = await repository.processUpdateActions(
244
249
  ctx,
245
250
  review,
246
251
  review.version,
@@ -256,7 +261,7 @@ describe("Review Repository", () => {
256
261
  expect(result.version).toBe(review.version + 1);
257
262
  });
258
263
 
259
- test("update review - setTitle", () => {
264
+ test("update review - setTitle", async () => {
260
265
  const draft: ReviewDraft = {
261
266
  authorName: "Test Author",
262
267
  title: "Original Title",
@@ -268,9 +273,9 @@ describe("Review Repository", () => {
268
273
  };
269
274
 
270
275
  const ctx = { projectKey: "dummy" };
271
- const review = repository.create(ctx, draft);
276
+ const review = await repository.create(ctx, draft);
272
277
 
273
- const result = repository.processUpdateActions(
278
+ const result = await repository.processUpdateActions(
274
279
  ctx,
275
280
  review,
276
281
  review.version,
@@ -286,7 +291,7 @@ describe("Review Repository", () => {
286
291
  expect(result.version).toBe(review.version + 1);
287
292
  });
288
293
 
289
- test("update review - setText", () => {
294
+ test("update review - setText", async () => {
290
295
  const draft: ReviewDraft = {
291
296
  authorName: "Test Author",
292
297
  title: "Test Review",
@@ -299,9 +304,9 @@ describe("Review Repository", () => {
299
304
  };
300
305
 
301
306
  const ctx = { projectKey: "dummy" };
302
- const review = repository.create(ctx, draft);
307
+ const review = await repository.create(ctx, draft);
303
308
 
304
- const result = repository.processUpdateActions(
309
+ const result = await repository.processUpdateActions(
305
310
  ctx,
306
311
  review,
307
312
  review.version,
@@ -317,7 +322,7 @@ describe("Review Repository", () => {
317
322
  expect(result.version).toBe(review.version + 1);
318
323
  });
319
324
 
320
- test("update review - setRating", () => {
325
+ test("update review - setRating", async () => {
321
326
  const draft: ReviewDraft = {
322
327
  authorName: "Test Author",
323
328
  title: "Test Review",
@@ -329,9 +334,9 @@ describe("Review Repository", () => {
329
334
  };
330
335
 
331
336
  const ctx = { projectKey: "dummy" };
332
- const review = repository.create(ctx, draft);
337
+ const review = await repository.create(ctx, draft);
333
338
 
334
- const result = repository.processUpdateActions(
339
+ const result = await repository.processUpdateActions(
335
340
  ctx,
336
341
  review,
337
342
  review.version,
@@ -347,7 +352,7 @@ describe("Review Repository", () => {
347
352
  expect(result.version).toBe(review.version + 1);
348
353
  });
349
354
 
350
- test("update review - setLocale", () => {
355
+ test("update review - setLocale", async () => {
351
356
  const draft: ReviewDraft = {
352
357
  authorName: "Test Author",
353
358
  title: "Test Review",
@@ -359,9 +364,9 @@ describe("Review Repository", () => {
359
364
  };
360
365
 
361
366
  const ctx = { projectKey: "dummy" };
362
- const review = repository.create(ctx, draft);
367
+ const review = await repository.create(ctx, draft);
363
368
 
364
- const result = repository.processUpdateActions(
369
+ const result = await repository.processUpdateActions(
365
370
  ctx,
366
371
  review,
367
372
  review.version,
@@ -377,7 +382,7 @@ describe("Review Repository", () => {
377
382
  expect(result.version).toBe(review.version + 1);
378
383
  });
379
384
 
380
- test("update review - setKey", () => {
385
+ test("update review - setKey", async () => {
381
386
  const draft: ReviewDraft = {
382
387
  key: "original-key",
383
388
  authorName: "Test Author",
@@ -390,9 +395,9 @@ describe("Review Repository", () => {
390
395
  };
391
396
 
392
397
  const ctx = { projectKey: "dummy" };
393
- const review = repository.create(ctx, draft);
398
+ const review = await repository.create(ctx, draft);
394
399
 
395
- const result = repository.processUpdateActions(
400
+ const result = await repository.processUpdateActions(
396
401
  ctx,
397
402
  review,
398
403
  review.version,
@@ -408,7 +413,7 @@ describe("Review Repository", () => {
408
413
  expect(result.version).toBe(review.version + 1);
409
414
  });
410
415
 
411
- test("update review - setCustomer", () => {
416
+ test("update review - setCustomer", async () => {
412
417
  const draft: ReviewDraft = {
413
418
  authorName: "Test Author",
414
419
  title: "Test Review",
@@ -420,9 +425,9 @@ describe("Review Repository", () => {
420
425
  };
421
426
 
422
427
  const ctx = { projectKey: "dummy" };
423
- const review = repository.create(ctx, draft);
428
+ const review = await repository.create(ctx, draft);
424
429
 
425
- const result = repository.processUpdateActions(
430
+ const result = await repository.processUpdateActions(
426
431
  ctx,
427
432
  review,
428
433
  review.version,
@@ -441,7 +446,7 @@ describe("Review Repository", () => {
441
446
  expect(result.version).toBe(review.version + 1);
442
447
  });
443
448
 
444
- test("update review - setTarget", () => {
449
+ test("update review - setTarget", async () => {
445
450
  const draft: ReviewDraft = {
446
451
  authorName: "Test Author",
447
452
  title: "Test Review",
@@ -453,9 +458,9 @@ describe("Review Repository", () => {
453
458
  };
454
459
 
455
460
  const ctx = { projectKey: "dummy" };
456
- const review = repository.create(ctx, draft);
461
+ const review = await repository.create(ctx, draft);
457
462
 
458
- const result = repository.processUpdateActions(
463
+ const result = await repository.processUpdateActions(
459
464
  ctx,
460
465
  review,
461
466
  review.version,
@@ -475,7 +480,7 @@ describe("Review Repository", () => {
475
480
  expect(result.version).toBe(review.version + 1);
476
481
  });
477
482
 
478
- test("update review - transitionState", () => {
483
+ test("update review - transitionState", async () => {
479
484
  const draft: ReviewDraft = {
480
485
  authorName: "Test Author",
481
486
  title: "Test Review",
@@ -487,9 +492,9 @@ describe("Review Repository", () => {
487
492
  };
488
493
 
489
494
  const ctx = { projectKey: "dummy" };
490
- const review = repository.create(ctx, draft);
495
+ const review = await repository.create(ctx, draft);
491
496
 
492
- const result = repository.processUpdateActions(
497
+ const result = await repository.processUpdateActions(
493
498
  ctx,
494
499
  review,
495
500
  review.version,
@@ -508,7 +513,7 @@ describe("Review Repository", () => {
508
513
  expect(result.version).toBe(review.version + 1);
509
514
  });
510
515
 
511
- test("update review - setCustomType", () => {
516
+ test("update review - setCustomType", async () => {
512
517
  const draft: ReviewDraft = {
513
518
  authorName: "Test Author",
514
519
  title: "Test Review",
@@ -520,10 +525,10 @@ describe("Review Repository", () => {
520
525
  };
521
526
 
522
527
  const ctx = { projectKey: "dummy" };
523
- const review = repository.create(ctx, draft);
528
+ const review = await repository.create(ctx, draft);
524
529
 
525
530
  // Set custom type
526
- const result = repository.processUpdateActions(
531
+ const result = await repository.processUpdateActions(
527
532
  ctx,
528
533
  review,
529
534
  review.version,
@@ -546,7 +551,7 @@ describe("Review Repository", () => {
546
551
  expect(result.version).toBe(review.version + 1);
547
552
 
548
553
  // Remove custom type
549
- const result2 = repository.processUpdateActions(
554
+ const result2 = await repository.processUpdateActions(
550
555
  ctx,
551
556
  result,
552
557
  result.version,
@@ -561,7 +566,7 @@ describe("Review Repository", () => {
561
566
  expect(result2.version).toBe(result.version + 1);
562
567
  });
563
568
 
564
- test("update review - setCustomField", () => {
569
+ test("update review - setCustomField", async () => {
565
570
  const draft: ReviewDraft = {
566
571
  authorName: "Test Author",
567
572
  title: "Test Review",
@@ -582,9 +587,9 @@ describe("Review Repository", () => {
582
587
  };
583
588
 
584
589
  const ctx = { projectKey: "dummy" };
585
- const review = repository.create(ctx, draft);
590
+ const review = await repository.create(ctx, draft);
586
591
 
587
- const result = repository.processUpdateActions(
592
+ const result = await repository.processUpdateActions(
588
593
  ctx,
589
594
  review,
590
595
  review.version,
@@ -601,7 +606,7 @@ describe("Review Repository", () => {
601
606
  expect(result.version).toBe(review.version + 1);
602
607
  });
603
608
 
604
- test("get and delete review", () => {
609
+ test("get and delete review", async () => {
605
610
  const draft: ReviewDraft = {
606
611
  key: "delete-test",
607
612
  authorName: "Test Author",
@@ -614,25 +619,25 @@ describe("Review Repository", () => {
614
619
  };
615
620
 
616
621
  const ctx = { projectKey: "dummy" };
617
- const review = repository.create(ctx, draft);
622
+ const review = await repository.create(ctx, draft);
618
623
 
619
624
  // Test get
620
- const retrieved = repository.get(ctx, review.id);
625
+ const retrieved = await repository.get(ctx, review.id);
621
626
  expect(retrieved).toBeDefined();
622
627
  expect(retrieved?.id).toBe(review.id);
623
628
 
624
629
  // Test getByKey
625
- const retrievedByKey = repository.getByKey(ctx, review.key!);
630
+ const retrievedByKey = await repository.getByKey(ctx, review.key!);
626
631
  expect(retrievedByKey).toBeDefined();
627
632
  expect(retrievedByKey?.key).toBe(review.key);
628
633
 
629
634
  // Test delete
630
- const deleted = repository.delete(ctx, review.id);
635
+ const deleted = await repository.delete(ctx, review.id);
631
636
  expect(deleted).toBeDefined();
632
637
  expect(deleted?.id).toBe(review.id);
633
638
 
634
639
  // Verify it's deleted
635
- const notFound = repository.get(ctx, review.id);
640
+ const notFound = await repository.get(ctx, review.id);
636
641
  expect(notFound).toBeNull();
637
642
  });
638
643
  });
@@ -2,6 +2,7 @@ import type {
2
2
  ChannelReference,
3
3
  CustomerReference,
4
4
  ProductReference,
5
+ RequiredFieldError,
5
6
  Review,
6
7
  ReviewDraft,
7
8
  ReviewSetAuthorNameAction,
@@ -19,6 +20,8 @@ import type {
19
20
  StateReference,
20
21
  } from "@commercetools/platform-sdk";
21
22
  import type { Config } from "#src/config.ts";
23
+ import { CommercetoolsError } from "#src/exceptions.ts";
24
+ import { ReviewDraftSchema } from "#src/schemas/generated/review.ts";
22
25
  import { getBaseResourceProperties } from "../helpers.ts";
23
26
  import type { Writable } from "../types.ts";
24
27
  import type { RepositoryContext, UpdateHandlerInterface } from "./abstract.ts";
@@ -35,12 +38,24 @@ export class ReviewRepository extends AbstractResourceRepository<"review"> {
35
38
  constructor(config: Config) {
36
39
  super("review", config);
37
40
  this.actions = new ReviewUpdateHandler(config.storage);
41
+ this.draftSchema = ReviewDraftSchema;
38
42
  }
39
43
 
40
- create(context: RepositoryContext, draft: ReviewDraft): Review {
41
- if (!draft.target) throw new Error("Missing target");
44
+ async create(
45
+ context: RepositoryContext,
46
+ draft: ReviewDraft,
47
+ ): Promise<Review> {
48
+ if (!draft.target)
49
+ throw new CommercetoolsError<RequiredFieldError>(
50
+ {
51
+ code: "RequiredField",
52
+ message: "Missing target",
53
+ field: "target",
54
+ },
55
+ 400,
56
+ );
42
57
  const resource: Review = {
43
- ...getBaseResourceProperties(),
58
+ ...getBaseResourceProperties(context.clientId),
44
59
  key: draft.key,
45
60
  locale: draft.locale,
46
61
  authorName: draft.authorName,
@@ -49,25 +64,25 @@ export class ReviewRepository extends AbstractResourceRepository<"review"> {
49
64
  rating: draft.rating,
50
65
  uniquenessValue: draft.uniquenessValue,
51
66
  state: draft.state
52
- ? getReferenceFromResourceIdentifier<StateReference>(
67
+ ? await getReferenceFromResourceIdentifier<StateReference>(
53
68
  draft.state,
54
69
  context.projectKey,
55
70
  this._storage,
56
71
  )
57
72
  : undefined,
58
73
  target: draft.target
59
- ? getReferenceFromResourceIdentifier<
74
+ ? await getReferenceFromResourceIdentifier<
60
75
  ProductReference | ChannelReference
61
76
  >(draft.target, context.projectKey, this._storage)
62
77
  : undefined,
63
78
  includedInStatistics: true,
64
- custom: createCustomFields(
79
+ custom: await createCustomFields(
65
80
  draft.custom,
66
81
  context.projectKey,
67
82
  this._storage,
68
83
  ),
69
84
  };
70
- return this.saveNew(context, resource);
85
+ return await this.saveNew(context, resource);
71
86
  }
72
87
  }
73
88
 
@@ -88,45 +103,24 @@ class ReviewUpdateHandler
88
103
  resource: Writable<Review>,
89
104
  { name, value }: ReviewSetCustomFieldAction,
90
105
  ) {
91
- if (!resource.custom) {
92
- throw new Error("Resource has no custom field");
93
- }
94
- resource.custom.fields[name] = value;
106
+ this._setCustomFieldValues(resource, { name, value });
95
107
  }
96
108
 
97
- setCustomType(
109
+ async setCustomType(
98
110
  context: RepositoryContext,
99
111
  resource: Writable<Review>,
100
112
  { type, fields }: ReviewSetCustomTypeAction,
101
113
  ) {
102
- if (!type) {
103
- resource.custom = undefined;
104
- } else {
105
- const resolvedType = this._storage.getByResourceIdentifier(
106
- context.projectKey,
107
- type,
108
- );
109
- if (!resolvedType) {
110
- throw new Error(`Type ${type} not found`);
111
- }
112
-
113
- resource.custom = {
114
- type: {
115
- typeId: "type",
116
- id: resolvedType.id,
117
- },
118
- fields: fields ?? {},
119
- };
120
- }
114
+ await this._setCustomType(context, resource, { type, fields });
121
115
  }
122
116
 
123
- setCustomer(
117
+ async setCustomer(
124
118
  context: RepositoryContext,
125
119
  resource: Writable<Review>,
126
120
  { customer }: ReviewSetCustomerAction,
127
121
  ) {
128
122
  resource.customer = customer
129
- ? getReferenceFromResourceIdentifier<CustomerReference>(
123
+ ? await getReferenceFromResourceIdentifier<CustomerReference>(
130
124
  customer,
131
125
  context.projectKey,
132
126
  this._storage,
@@ -158,12 +152,12 @@ class ReviewUpdateHandler
158
152
  resource.rating = rating;
159
153
  }
160
154
 
161
- setTarget(
155
+ async setTarget(
162
156
  context: RepositoryContext,
163
157
  resource: Writable<Review>,
164
158
  { target }: ReviewSetTargetAction,
165
159
  ) {
166
- resource.target = getReferenceFromResourceIdentifier<
160
+ resource.target = await getReferenceFromResourceIdentifier<
167
161
  ProductReference | ChannelReference
168
162
  >(target, context.projectKey, this._storage);
169
163
  }
@@ -184,12 +178,12 @@ class ReviewUpdateHandler
184
178
  resource.title = title;
185
179
  }
186
180
 
187
- transitionState(
181
+ async transitionState(
188
182
  context: RepositoryContext,
189
183
  resource: Writable<Review>,
190
184
  { state }: ReviewTransitionStateAction,
191
185
  ) {
192
- resource.state = getReferenceFromResourceIdentifier<StateReference>(
186
+ resource.state = await getReferenceFromResourceIdentifier<StateReference>(
193
187
  state,
194
188
  context.projectKey,
195
189
  this._storage,