@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,13 +1,14 @@
1
- import type { DiscountGroupDraft } from "@commercetools/platform-sdk";
2
- import supertest from "supertest";
3
1
  import { describe, expect, test } from "vitest";
2
+ import { discountGroupDraftFactory } 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("DiscountGroup", () => {
8
+ const discountGroupDraft = discountGroupDraftFactory(ctMock);
9
+
9
10
  test("Create discount group", async () => {
10
- const draft: DiscountGroupDraft = {
11
+ const draft = discountGroupDraft.build({
11
12
  key: "premium-discount-group",
12
13
  name: {
13
14
  "en-GB": "Premium Discount Group",
@@ -16,113 +17,100 @@ describe("DiscountGroup", () => {
16
17
  "en-GB": "A discount group for premium customers",
17
18
  },
18
19
  sortOrder: "0.5",
19
- };
20
- const response = await supertest(ctMock.app)
21
- .post("/dummy/discount-groups")
22
- .send(draft);
23
-
24
- expect(response.status).toBe(201);
20
+ });
25
21
 
26
- expect(response.body).toEqual({
27
- createdAt: expect.anything(),
28
- id: expect.anything(),
29
- key: "premium-discount-group",
30
- isActive: true,
31
- lastModifiedAt: expect.anything(),
32
- name: {
33
- "en-GB": "Premium Discount Group",
34
- },
35
- description: {
36
- "en-GB": "A discount group for premium customers",
37
- },
38
- sortOrder: "0.5",
39
- version: 1,
22
+ const response = await ctMock.app.inject({
23
+ method: "POST",
24
+ url: "/dummy/discount-groups",
25
+ payload: draft,
40
26
  });
27
+
28
+ expect(response.statusCode).toBe(201);
29
+ expect(response.json()).toEqual(
30
+ expect.objectContaining({
31
+ key: "premium-discount-group",
32
+ isActive: true,
33
+ name: expect.objectContaining({
34
+ "en-GB": "Premium Discount Group",
35
+ }),
36
+ description: {
37
+ "en-GB": "A discount group for premium customers",
38
+ },
39
+ sortOrder: "0.5",
40
+ version: 1,
41
+ }),
42
+ );
41
43
  });
42
44
 
43
45
  test("Get discount group", async () => {
44
- const draft: DiscountGroupDraft = {
46
+ const discountGroup = await discountGroupDraft.create({
45
47
  key: "test-discount-group",
46
48
  name: {
47
49
  "en-GB": "Test Discount Group",
48
50
  },
49
51
  sortOrder: "0.1",
50
- };
51
- const createResponse = await supertest(ctMock.app)
52
- .post("/dummy/discount-groups")
53
- .send(draft);
54
-
55
- expect(createResponse.status).toBe(201);
52
+ });
56
53
 
57
- const response = await supertest(ctMock.app).get(
58
- `/dummy/discount-groups/${createResponse.body.id}`,
59
- );
54
+ const response = await ctMock.app.inject({
55
+ method: "GET",
56
+ url: `/dummy/discount-groups/${discountGroup.id}`,
57
+ });
60
58
 
61
- expect(response.status).toBe(200);
62
- expect(response.body).toEqual(createResponse.body);
59
+ expect(response.statusCode).toBe(200);
60
+ expect(response.json()).toEqual(discountGroup);
63
61
  });
64
62
 
65
63
  test("Get discount group by key", async () => {
66
- const draft: DiscountGroupDraft = {
64
+ const discountGroup = await discountGroupDraft.create({
67
65
  key: "key-discount-group",
68
66
  name: {
69
67
  "en-GB": "Key Discount Group",
70
68
  },
71
69
  sortOrder: "0.2",
72
- };
73
- const createResponse = await supertest(ctMock.app)
74
- .post("/dummy/discount-groups")
75
- .send(draft);
76
-
77
- expect(createResponse.status).toBe(201);
70
+ });
78
71
 
79
- const response = await supertest(ctMock.app).get(
80
- "/dummy/discount-groups/key=key-discount-group",
81
- );
72
+ const response = await ctMock.app.inject({
73
+ method: "GET",
74
+ url: "/dummy/discount-groups/key=key-discount-group",
75
+ });
82
76
 
83
- expect(response.status).toBe(200);
84
- expect(response.body).toEqual(createResponse.body);
77
+ expect(response.statusCode).toBe(200);
78
+ expect(response.json()).toEqual(discountGroup);
85
79
  });
86
80
 
87
81
  test("Query discount groups", async () => {
88
- const draft: DiscountGroupDraft = {
82
+ const discountGroup = await discountGroupDraft.create({
89
83
  key: "query-discount-group",
90
84
  name: {
91
85
  "en-GB": "Query Discount Group",
92
86
  },
93
87
  sortOrder: "0.3",
94
- };
95
- const createResponse = await supertest(ctMock.app)
96
- .post("/dummy/discount-groups")
97
- .send(draft);
98
-
99
- expect(createResponse.status).toBe(201);
88
+ });
100
89
 
101
- const response = await supertest(ctMock.app).get("/dummy/discount-groups");
90
+ const response = await ctMock.app.inject({
91
+ method: "GET",
92
+ url: "/dummy/discount-groups",
93
+ });
102
94
 
103
- expect(response.status).toBe(200);
104
- expect(response.body.count).toBeGreaterThan(0);
105
- expect(response.body.results).toContainEqual(createResponse.body);
95
+ expect(response.statusCode).toBe(200);
96
+ expect(response.json().count).toBeGreaterThan(0);
97
+ expect(response.json().results).toContainEqual(discountGroup);
106
98
  });
107
99
 
108
100
  test("Update discount group - setName", async () => {
109
- const draft: DiscountGroupDraft = {
101
+ const discountGroup = await discountGroupDraft.create({
110
102
  key: "update-name-group",
111
103
  name: {
112
104
  "en-GB": "Original Name",
113
105
  },
114
106
  sortOrder: "0.4",
115
- };
116
- const createResponse = await supertest(ctMock.app)
117
- .post("/dummy/discount-groups")
118
- .send(draft);
119
-
120
- expect(createResponse.status).toBe(201);
107
+ });
121
108
 
122
- const updateResponse = await supertest(ctMock.app)
123
- .post(`/dummy/discount-groups/${createResponse.body.id}`)
124
- .send({
125
- version: createResponse.body.version,
109
+ const updateResponse = await ctMock.app.inject({
110
+ method: "POST",
111
+ url: `/dummy/discount-groups/${discountGroup.id}`,
112
+ payload: {
113
+ version: discountGroup.version,
126
114
  actions: [
127
115
  {
128
116
  action: "setName",
@@ -132,34 +120,31 @@ describe("DiscountGroup", () => {
132
120
  },
133
121
  },
134
122
  ],
135
- });
123
+ },
124
+ });
136
125
 
137
- expect(updateResponse.status).toBe(200);
138
- expect(updateResponse.body.name).toEqual({
126
+ expect(updateResponse.statusCode).toBe(200);
127
+ expect(updateResponse.json().name).toEqual({
139
128
  "en-GB": "Updated Name",
140
129
  de: "Aktualisierter Name",
141
130
  });
142
- expect(updateResponse.body.version).toBe(2);
131
+ expect(updateResponse.json().version).toBe(2);
143
132
  });
144
133
 
145
134
  test("Update discount group - setDescription", async () => {
146
- const draft: DiscountGroupDraft = {
135
+ const discountGroup = await discountGroupDraft.create({
147
136
  key: "update-description-group",
148
137
  name: {
149
138
  "en-GB": "Test Group",
150
139
  },
151
140
  sortOrder: "0.5",
152
- };
153
- const createResponse = await supertest(ctMock.app)
154
- .post("/dummy/discount-groups")
155
- .send(draft);
156
-
157
- expect(createResponse.status).toBe(201);
141
+ });
158
142
 
159
- const updateResponse = await supertest(ctMock.app)
160
- .post(`/dummy/discount-groups/${createResponse.body.id}`)
161
- .send({
162
- version: createResponse.body.version,
143
+ const updateResponse = await ctMock.app.inject({
144
+ method: "POST",
145
+ url: `/dummy/discount-groups/${discountGroup.id}`,
146
+ payload: {
147
+ version: discountGroup.version,
163
148
  actions: [
164
149
  {
165
150
  action: "setDescription",
@@ -169,103 +154,95 @@ describe("DiscountGroup", () => {
169
154
  },
170
155
  },
171
156
  ],
172
- });
157
+ },
158
+ });
173
159
 
174
- expect(updateResponse.status).toBe(200);
175
- expect(updateResponse.body.description).toEqual({
160
+ expect(updateResponse.statusCode).toBe(200);
161
+ expect(updateResponse.json().description).toEqual({
176
162
  "en-GB": "New description",
177
163
  de: "Neue Beschreibung",
178
164
  });
179
- expect(updateResponse.body.version).toBe(2);
165
+ expect(updateResponse.json().version).toBe(2);
180
166
  });
181
167
 
182
168
  test("Update discount group - setKey", async () => {
183
- const draft: DiscountGroupDraft = {
169
+ const discountGroup = await discountGroupDraft.create({
184
170
  key: "original-key",
185
171
  name: {
186
172
  "en-GB": "Test Group",
187
173
  },
188
174
  sortOrder: "0.6",
189
- };
190
- const createResponse = await supertest(ctMock.app)
191
- .post("/dummy/discount-groups")
192
- .send(draft);
193
-
194
- expect(createResponse.status).toBe(201);
175
+ });
195
176
 
196
- const updateResponse = await supertest(ctMock.app)
197
- .post(`/dummy/discount-groups/${createResponse.body.id}`)
198
- .send({
199
- version: createResponse.body.version,
177
+ const updateResponse = await ctMock.app.inject({
178
+ method: "POST",
179
+ url: `/dummy/discount-groups/${discountGroup.id}`,
180
+ payload: {
181
+ version: discountGroup.version,
200
182
  actions: [
201
183
  {
202
184
  action: "setKey",
203
185
  key: "updated-key",
204
186
  },
205
187
  ],
206
- });
188
+ },
189
+ });
207
190
 
208
- expect(updateResponse.status).toBe(200);
209
- expect(updateResponse.body.key).toBe("updated-key");
210
- expect(updateResponse.body.version).toBe(2);
191
+ expect(updateResponse.statusCode).toBe(200);
192
+ expect(updateResponse.json().key).toBe("updated-key");
193
+ expect(updateResponse.json().version).toBe(2);
211
194
  });
212
195
 
213
196
  test("Update discount group - setSortOrder", async () => {
214
- const draft: DiscountGroupDraft = {
197
+ const discountGroup = await discountGroupDraft.create({
215
198
  key: "sort-order-group",
216
199
  name: {
217
200
  "en-GB": "Sort Order Group",
218
201
  },
219
202
  sortOrder: "0.1",
220
- };
221
- const createResponse = await supertest(ctMock.app)
222
- .post("/dummy/discount-groups")
223
- .send(draft);
224
-
225
- expect(createResponse.status).toBe(201);
203
+ });
226
204
 
227
- const updateResponse = await supertest(ctMock.app)
228
- .post(`/dummy/discount-groups/${createResponse.body.id}`)
229
- .send({
230
- version: createResponse.body.version,
205
+ const updateResponse = await ctMock.app.inject({
206
+ method: "POST",
207
+ url: `/dummy/discount-groups/${discountGroup.id}`,
208
+ payload: {
209
+ version: discountGroup.version,
231
210
  actions: [
232
211
  {
233
212
  action: "setSortOrder",
234
213
  sortOrder: "0.9",
235
214
  },
236
215
  ],
237
- });
216
+ },
217
+ });
238
218
 
239
- expect(updateResponse.status).toBe(200);
240
- expect(updateResponse.body.sortOrder).toBe("0.9");
241
- expect(updateResponse.body.version).toBe(2);
219
+ expect(updateResponse.statusCode).toBe(200);
220
+ expect(updateResponse.json().sortOrder).toBe("0.9");
221
+ expect(updateResponse.json().version).toBe(2);
242
222
  });
243
223
 
244
224
  test("Delete discount group", async () => {
245
- const draft: DiscountGroupDraft = {
225
+ const discountGroup = await discountGroupDraft.create({
246
226
  key: "delete-group",
247
227
  name: {
248
228
  "en-GB": "Delete Group",
249
229
  },
250
230
  sortOrder: "0.7",
251
- };
252
- const createResponse = await supertest(ctMock.app)
253
- .post("/dummy/discount-groups")
254
- .send(draft);
255
-
256
- expect(createResponse.status).toBe(201);
231
+ });
257
232
 
258
- const deleteResponse = await supertest(ctMock.app)
259
- .delete(`/dummy/discount-groups/${createResponse.body.id}`)
260
- .query({ version: createResponse.body.version });
233
+ const deleteResponse = await ctMock.app.inject({
234
+ method: "DELETE",
235
+ url: `/dummy/discount-groups/${discountGroup.id}?version=${discountGroup.version}`,
236
+ });
261
237
 
262
- expect(deleteResponse.status).toBe(200);
263
- expect(deleteResponse.body).toEqual(createResponse.body);
238
+ expect(deleteResponse.statusCode).toBe(200);
239
+ expect(deleteResponse.json()).toEqual(discountGroup);
264
240
 
265
- const getResponse = await supertest(ctMock.app).get(
266
- `/dummy/discount-groups/${createResponse.body.id}`,
267
- );
241
+ const getResponse = await ctMock.app.inject({
242
+ method: "GET",
243
+ url: `/dummy/discount-groups/${discountGroup.id}`,
244
+ });
268
245
 
269
- expect(getResponse.status).toBe(404);
246
+ expect(getResponse.statusCode).toBe(404);
270
247
  });
271
248
  });
@@ -1,11 +1,11 @@
1
- import type { Router } from "express";
1
+ import type { FastifyInstance } from "fastify";
2
2
  import type { DiscountGroupRepository } from "../repositories/discount-group/index.ts";
3
3
  import AbstractService from "./abstract.ts";
4
4
 
5
5
  export class DiscountGroupService extends AbstractService {
6
6
  public repository: DiscountGroupRepository;
7
7
 
8
- constructor(parent: Router, repository: DiscountGroupRepository) {
8
+ constructor(parent: FastifyInstance, repository: DiscountGroupRepository) {
9
9
  super(parent);
10
10
  this.repository = repository;
11
11
  }
@@ -0,0 +1,255 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { CommercetoolsMock } from "../index.ts";
3
+
4
+ describe("Draft validation (strict mode)", () => {
5
+ const ctMock = new CommercetoolsMock({ strict: true });
6
+
7
+ describe("ZoneDraft", () => {
8
+ test("accepts valid draft", async () => {
9
+ const response = await ctMock.app.inject({
10
+ method: "POST",
11
+ url: "/dummy/zones",
12
+ payload: {
13
+ name: "Europe",
14
+ key: "europe",
15
+ locations: [{ country: "DE" }, { country: "NL" }],
16
+ },
17
+ });
18
+ expect(response.statusCode).toBe(201);
19
+ expect(response.json().name).toBe("Europe");
20
+ });
21
+
22
+ test("rejects draft without required 'name' field", async () => {
23
+ const response = await ctMock.app.inject({
24
+ method: "POST",
25
+ url: "/dummy/zones",
26
+ payload: {
27
+ key: "missing-name",
28
+ },
29
+ });
30
+ expect(response.statusCode).toBe(400);
31
+ const body = response.json();
32
+ expect(body.errors[0].code).toBe("InvalidJsonInput");
33
+ expect(body.errors[0].detailedErrorMessage).toBe(
34
+ "name: Missing required value",
35
+ );
36
+ });
37
+
38
+ test("rejects draft with wrong type for 'name'", async () => {
39
+ const response = await ctMock.app.inject({
40
+ method: "POST",
41
+ url: "/dummy/zones",
42
+ payload: {
43
+ name: 123,
44
+ },
45
+ });
46
+ expect(response.statusCode).toBe(400);
47
+ const body = response.json();
48
+ expect(body.errors[0].code).toBe("InvalidJsonInput");
49
+ expect(body.errors[0].detailedErrorMessage).toBe(
50
+ "name: JSON String expected.",
51
+ );
52
+ });
53
+
54
+ test("accepts draft with extra fields (looseObject)", async () => {
55
+ const response = await ctMock.app.inject({
56
+ method: "POST",
57
+ url: "/dummy/zones",
58
+ payload: {
59
+ name: "Test",
60
+ someExtraField: "should be ignored",
61
+ },
62
+ });
63
+ expect(response.statusCode).toBe(201);
64
+ });
65
+ });
66
+
67
+ describe("ChannelDraft", () => {
68
+ test("accepts valid draft", async () => {
69
+ const response = await ctMock.app.inject({
70
+ method: "POST",
71
+ url: "/dummy/channels",
72
+ payload: {
73
+ key: "my-channel",
74
+ roles: ["InventorySupply"],
75
+ },
76
+ });
77
+ expect(response.statusCode).toBe(201);
78
+ expect(response.json().key).toBe("my-channel");
79
+ });
80
+
81
+ test("rejects draft without required 'key' field", async () => {
82
+ const response = await ctMock.app.inject({
83
+ method: "POST",
84
+ url: "/dummy/channels",
85
+ payload: {
86
+ roles: ["InventorySupply"],
87
+ },
88
+ });
89
+ expect(response.statusCode).toBe(400);
90
+ const body = response.json();
91
+ expect(body.errors[0].code).toBe("InvalidJsonInput");
92
+ expect(body.errors[0].detailedErrorMessage).toBe(
93
+ "key: Missing required value",
94
+ );
95
+ });
96
+
97
+ test("rejects draft with invalid role enum value", async () => {
98
+ const response = await ctMock.app.inject({
99
+ method: "POST",
100
+ url: "/dummy/channels",
101
+ payload: {
102
+ key: "bad-roles",
103
+ roles: ["InvalidRole"],
104
+ },
105
+ });
106
+ expect(response.statusCode).toBe(400);
107
+ const body = response.json();
108
+ expect(body.errors[0].code).toBe("InvalidJsonInput");
109
+ expect(body.errors[0].detailedErrorMessage).toContain(
110
+ "Invalid enum value",
111
+ );
112
+ });
113
+
114
+ test("accepts draft with localized name", async () => {
115
+ const response = await ctMock.app.inject({
116
+ method: "POST",
117
+ url: "/dummy/channels",
118
+ payload: {
119
+ key: "localized-channel",
120
+ name: { en: "English", de: "Deutsch" },
121
+ },
122
+ });
123
+ expect(response.statusCode).toBe(201);
124
+ });
125
+ });
126
+
127
+ describe("InventoryEntryDraft", () => {
128
+ test("accepts valid draft", async () => {
129
+ const response = await ctMock.app.inject({
130
+ method: "POST",
131
+ url: "/dummy/inventory",
132
+ payload: {
133
+ key: "ie-key-1",
134
+ sku: "sku_variant1",
135
+ quantityOnStock: 4,
136
+ },
137
+ });
138
+ expect(response.statusCode).toBe(201);
139
+ expect(response.json().sku).toBe("sku_variant1");
140
+ });
141
+
142
+ test("rejects draft with typo in required field name (quantityOnStxock)", async () => {
143
+ const response = await ctMock.app.inject({
144
+ method: "POST",
145
+ url: "/dummy/inventory",
146
+ payload: {
147
+ key: "ie-key-1",
148
+ sku: "sku_variant1",
149
+ quantityOnStxock: 4, // typo — real field is quantityOnStock
150
+ },
151
+ });
152
+ expect(response.statusCode).toBe(400);
153
+ const body = response.json();
154
+ expect(body.errors[0].code).toBe("InvalidJsonInput");
155
+ expect(body.errors[0].detailedErrorMessage).toBe(
156
+ "quantityOnStock: Missing required value",
157
+ );
158
+ });
159
+
160
+ test("rejects draft without required 'sku' field", async () => {
161
+ const response = await ctMock.app.inject({
162
+ method: "POST",
163
+ url: "/dummy/inventory",
164
+ payload: {
165
+ quantityOnStock: 10,
166
+ },
167
+ });
168
+ expect(response.statusCode).toBe(400);
169
+ const body = response.json();
170
+ expect(body.errors[0].code).toBe("InvalidJsonInput");
171
+ expect(body.errors[0].detailedErrorMessage).toBe(
172
+ "sku: Missing required value",
173
+ );
174
+ });
175
+ });
176
+
177
+ describe("CustomerDraft", () => {
178
+ test("accepts valid draft", async () => {
179
+ const response = await ctMock.app.inject({
180
+ method: "POST",
181
+ url: "/dummy/customers",
182
+ payload: {
183
+ email: "test@example.com",
184
+ password: "secret123",
185
+ },
186
+ });
187
+ expect(response.statusCode).toBe(201);
188
+ });
189
+
190
+ test("rejects draft without required 'email' field", async () => {
191
+ const response = await ctMock.app.inject({
192
+ method: "POST",
193
+ url: "/dummy/customers",
194
+ payload: {
195
+ password: "secret123",
196
+ },
197
+ });
198
+ expect(response.statusCode).toBe(400);
199
+ const body = response.json();
200
+ expect(body.errors[0].code).toBe("InvalidJsonInput");
201
+ expect(body.errors[0].detailedErrorMessage).toBe(
202
+ "email: Missing required value",
203
+ );
204
+ });
205
+
206
+ test("accepts draft with addresses", async () => {
207
+ const response = await ctMock.app.inject({
208
+ method: "POST",
209
+ url: "/dummy/customers",
210
+ payload: {
211
+ email: "address@example.com",
212
+ password: "secret123",
213
+ addresses: [
214
+ {
215
+ country: "DE",
216
+ city: "Berlin",
217
+ streetName: "Main Street",
218
+ },
219
+ ],
220
+ },
221
+ });
222
+ expect(response.statusCode).toBe(201);
223
+ });
224
+ });
225
+ });
226
+
227
+ describe("Draft validation (non-strict mode - default)", () => {
228
+ const ctMock = new CommercetoolsMock();
229
+
230
+ test("allows invalid zone draft when strict is false", async () => {
231
+ const response = await ctMock.app.inject({
232
+ method: "POST",
233
+ url: "/dummy/zones",
234
+ payload: {
235
+ // missing required 'name' field
236
+ key: "no-name-zone",
237
+ },
238
+ });
239
+ // Without strict mode, validation is skipped and the
240
+ // repository creates the resource (name will be undefined)
241
+ expect(response.statusCode).toBe(201);
242
+ });
243
+
244
+ test("allows invalid channel draft when strict is false", async () => {
245
+ const response = await ctMock.app.inject({
246
+ method: "POST",
247
+ url: "/dummy/channels",
248
+ payload: {
249
+ // missing required 'key' field
250
+ roles: ["InventorySupply"],
251
+ },
252
+ });
253
+ expect(response.statusCode).toBe(201);
254
+ });
255
+ });