@labdigital/commercetools-mock 2.65.1 → 3.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +3771 -2654
  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 +89 -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,23 +1,29 @@
1
1
  import type { CustomObject } from "@commercetools/platform-sdk";
2
- import supertest from "supertest";
3
2
  import { afterEach, beforeEach, describe, expect, test } from "vitest";
3
+ import { customObjectDraftFactory } from "#src/testing/index.ts";
4
4
  import { getBaseResourceProperties } from "../helpers.ts";
5
5
  import { CommercetoolsMock } from "../index.ts";
6
6
 
7
7
  describe("CustomObject create", () => {
8
8
  const ctMock = new CommercetoolsMock();
9
+ const customObjectDraft = customObjectDraftFactory(ctMock);
9
10
 
10
11
  test("Create new object", async () => {
11
- const response = await supertest(ctMock.app)
12
- .post("/dummy/custom-objects")
13
- .send({
14
- container: "my-container",
15
- key: "my-key",
16
- value: "my-value",
17
- });
12
+ const draft = customObjectDraft.build({
13
+ container: "my-container",
14
+ key: "my-key",
15
+ value: "my-value",
16
+ });
17
+
18
+ const response = await ctMock.app.inject({
19
+ method: "POST",
20
+ url: "/dummy/custom-objects",
21
+ payload: draft,
22
+ });
23
+
24
+ expect(response.statusCode).toBe(201);
18
25
 
19
- expect(response.status).toBe(201);
20
- const customObject = response.body;
26
+ const customObject = response.json();
21
27
  expect(customObject.container).toBe("my-container");
22
28
  expect(customObject.key).toBe("my-key");
23
29
  expect(customObject.value).toBe("my-value");
@@ -26,19 +32,16 @@ describe("CustomObject create", () => {
26
32
 
27
33
  describe("CustomObject retrieve", () => {
28
34
  const ctMock = new CommercetoolsMock();
35
+ const customObjectDraft = customObjectDraftFactory(ctMock);
29
36
  let customObject: CustomObject;
30
37
 
31
38
  beforeEach(async () => {
32
- const response = await supertest(ctMock.app)
33
- .post("/dummy/custom-objects")
34
- .send({
35
- container: "my-container",
36
- key: "my-key",
37
- value: "my-value",
38
- });
39
+ customObject = await customObjectDraft.create({
40
+ container: "my-container",
41
+ key: "my-key",
42
+ value: "my-value",
43
+ });
39
44
 
40
- expect(response.status).toBe(201);
41
- customObject = response.body;
42
45
  expect(customObject.container).toBe("my-container");
43
46
  expect(customObject.key).toBe("my-key");
44
47
  expect(customObject.value).toBe("my-value");
@@ -48,40 +51,44 @@ describe("CustomObject retrieve", () => {
48
51
  });
49
52
 
50
53
  test("exists", async () => {
51
- const response = await supertest(ctMock.app)
52
- .head("/dummy/custom-objects/my-container/my-key")
53
- .send();
54
+ const response = await ctMock.app.inject({
55
+ method: "HEAD",
56
+ url: "/dummy/custom-objects/my-container/my-key",
57
+ });
54
58
 
55
- expect(response.status).toBe(200);
59
+ expect(response.statusCode).toBe(200);
56
60
  });
57
61
 
58
62
  test("non-existent", async () => {
59
- const response = await supertest(ctMock.app)
60
- .head("/dummy/custom-objects/invalid-container/invalid")
61
- .send();
63
+ const response = await ctMock.app.inject({
64
+ method: "HEAD",
65
+ url: "/dummy/custom-objects/invalid-container/invalid",
66
+ });
62
67
 
63
- expect(response.status).toBe(404);
68
+ expect(response.statusCode).toBe(404);
64
69
  });
65
70
 
66
71
  test("get", async () => {
67
- const response = await supertest(ctMock.app)
68
- .get("/dummy/custom-objects/my-container/my-key")
69
- .send();
72
+ const response = await ctMock.app.inject({
73
+ method: "GET",
74
+ url: "/dummy/custom-objects/my-container/my-key",
75
+ });
70
76
 
71
- expect(response.status).toBe(200);
72
- const customObject = response.body;
73
- expect(customObject.container).toBe("my-container");
74
- expect(customObject.key).toBe("my-key");
75
- expect(customObject.value).toBe("my-value");
77
+ expect(response.statusCode).toBe(200);
78
+ const result = response.json();
79
+ expect(result.container).toBe("my-container");
80
+ expect(result.key).toBe("my-key");
81
+ expect(result.value).toBe("my-value");
76
82
  });
77
83
 
78
84
  test("query with container", async () => {
79
- const response = await supertest(ctMock.app)
80
- .get("/dummy/custom-objects/my-container")
81
- .send();
85
+ const response = await ctMock.app.inject({
86
+ method: "GET",
87
+ url: "/dummy/custom-objects/my-container",
88
+ });
82
89
 
83
- expect(response.status).toBe(200);
84
- const customObjects = response.body;
90
+ expect(response.statusCode).toBe(200);
91
+ const customObjects = response.json();
85
92
  expect(customObjects).toMatchObject({
86
93
  results: [
87
94
  {
@@ -95,29 +102,33 @@ describe("CustomObject retrieve", () => {
95
102
  });
96
103
 
97
104
  test("Update match current (no conflict)", async () => {
98
- const response = await supertest(ctMock.app)
99
- .post("/dummy/custom-objects")
100
- .send({
105
+ const response = await ctMock.app.inject({
106
+ method: "POST",
107
+ url: "/dummy/custom-objects",
108
+ payload: {
101
109
  container: "my-container",
102
110
  key: "my-key",
103
111
  value: "my-value",
104
- });
112
+ },
113
+ });
105
114
 
106
- expect(response.status).toBe(201);
115
+ expect(response.statusCode).toBe(201);
107
116
  });
108
117
 
109
118
  test("New with version (errors)", async () => {
110
- const response = await supertest(ctMock.app)
111
- .post("/dummy/custom-objects")
112
- .send({
119
+ const response = await ctMock.app.inject({
120
+ method: "POST",
121
+ url: "/dummy/custom-objects",
122
+ payload: {
113
123
  container: "my-new-container",
114
124
  key: "my-new-key",
115
125
  value: "my-value",
116
126
  version: 2,
117
- });
127
+ },
128
+ });
118
129
 
119
- expect(response.status).toBe(400);
120
- expect(response.body).toStrictEqual({
130
+ expect(response.statusCode).toBe(400);
131
+ expect(response.json()).toStrictEqual({
121
132
  statusCode: 400,
122
133
  message: "version on create must be 0",
123
134
  errors: [
@@ -130,17 +141,19 @@ describe("CustomObject retrieve", () => {
130
141
  });
131
142
 
132
143
  test("Update match current with version (conflict)", async () => {
133
- const response = await supertest(ctMock.app)
134
- .post("/dummy/custom-objects")
135
- .send({
144
+ const response = await ctMock.app.inject({
145
+ method: "POST",
146
+ url: "/dummy/custom-objects",
147
+ payload: {
136
148
  container: "my-container",
137
149
  key: "my-key",
138
150
  value: "my-value",
139
151
  version: 2,
140
- });
152
+ },
153
+ });
141
154
 
142
- expect(response.status).toBe(409);
143
- expect(response.body).toStrictEqual({
155
+ expect(response.statusCode).toBe(409);
156
+ expect(response.json()).toStrictEqual({
144
157
  statusCode: 409,
145
158
  message: `Object ${customObject.id} has a different version than expected. Expected: 2 - Actual: 1.`,
146
159
  errors: [
@@ -154,7 +167,7 @@ describe("CustomObject retrieve", () => {
154
167
  });
155
168
 
156
169
  test("can use the add function with the custom object name", async () => {
157
- ctMock.project("dummy").add("key-value-document", {
170
+ ctMock.project("dummy").unsafeAdd("key-value-document", {
158
171
  ...getBaseResourceProperties(),
159
172
  container: "my-container",
160
173
  key: "my-key",
@@ -162,24 +175,27 @@ describe("CustomObject retrieve", () => {
162
175
  version: 2,
163
176
  });
164
177
 
165
- const response = await supertest(ctMock.app)
166
- .get("/dummy/custom-objects/my-container/my-key")
167
- .send();
178
+ const response = await ctMock.app.inject({
179
+ method: "GET",
180
+ url: "/dummy/custom-objects/my-container/my-key",
181
+ });
168
182
 
169
- expect(response.status).toEqual(200);
170
- expect(response.body).toEqual({
183
+ expect(response.statusCode).toEqual(200);
184
+ expect(response.json()).toEqual({
171
185
  container: "my-container",
172
186
  createdAt: expect.anything(),
187
+ createdBy: expect.anything(),
173
188
  id: expect.anything(),
174
189
  key: "my-key",
175
190
  lastModifiedAt: expect.anything(),
191
+ lastModifiedBy: expect.anything(),
176
192
  value: "my-value",
177
193
  version: 1,
178
194
  });
179
195
  });
180
196
 
181
197
  test("update with container and key", async () => {
182
- ctMock.project("dummy").add("key-value-document", {
198
+ ctMock.project("dummy").unsafeAdd("key-value-document", {
183
199
  ...getBaseResourceProperties(),
184
200
  container: "my-other-container",
185
201
  key: "my-key",
@@ -187,44 +203,52 @@ describe("CustomObject retrieve", () => {
187
203
  version: 2,
188
204
  });
189
205
 
190
- const response = await supertest(ctMock.app)
191
- .post("/dummy/custom-objects/my-other-container/my-key")
192
- .send({
206
+ const response = await ctMock.app.inject({
207
+ method: "POST",
208
+ url: "/dummy/custom-objects/my-other-container/my-key",
209
+ payload: {
193
210
  value: "new-value",
194
- });
211
+ },
212
+ });
195
213
 
196
- expect(response.status).toEqual(200);
197
- expect(response.body).toEqual({
214
+ expect(response.statusCode).toEqual(200);
215
+ expect(response.json()).toEqual({
198
216
  container: "my-other-container",
199
217
  createdAt: expect.anything(),
218
+ createdBy: expect.anything(),
200
219
  id: expect.anything(),
201
220
  key: "my-key",
202
221
  lastModifiedAt: expect.anything(),
222
+ lastModifiedBy: expect.anything(),
203
223
  value: "new-value",
204
224
  version: 3,
205
225
  });
206
226
  });
207
227
 
208
228
  test("delete with container and key", async () => {
209
- const response = await supertest(ctMock.app)
210
- .delete("/dummy/custom-objects/my-container/my-key")
211
- .send();
229
+ const response = await ctMock.app.inject({
230
+ method: "DELETE",
231
+ url: "/dummy/custom-objects/my-container/my-key",
232
+ });
212
233
 
213
- expect(response.status).toEqual(200);
214
- expect(response.body).toEqual({
234
+ expect(response.statusCode).toEqual(200);
235
+ expect(response.json()).toEqual({
215
236
  container: "my-container",
216
237
  createdAt: expect.anything(),
238
+ createdBy: expect.anything(),
217
239
  id: expect.anything(),
218
240
  key: "my-key",
219
241
  lastModifiedAt: expect.anything(),
242
+ lastModifiedBy: expect.anything(),
220
243
  value: "my-value",
221
244
  version: 1,
222
245
  });
223
246
 
224
- const fetchRes = await supertest(ctMock.app)
225
- .get("/dummy/custom-objects/my-container/my-key")
226
- .send();
247
+ const fetchRes = await ctMock.app.inject({
248
+ method: "GET",
249
+ url: "/dummy/custom-objects/my-container/my-key",
250
+ });
227
251
 
228
- expect(fetchRes.status).toEqual(404);
252
+ expect(fetchRes.statusCode).toEqual(404);
229
253
  });
230
254
  });
@@ -1,5 +1,9 @@
1
- import type { CustomObjectDraft } from "@commercetools/platform-sdk";
2
- import type { Request, Response, Router } from "express";
1
+ import type {
2
+ CustomObjectDraft,
3
+ ResourceNotFoundError,
4
+ } from "@commercetools/platform-sdk";
5
+ import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
6
+ import { CommercetoolsError } from "#src/exceptions.ts";
3
7
  import type { CustomObjectRepository } from "../repositories/custom-object.ts";
4
8
  import { getRepositoryContext } from "../repositories/helpers.ts";
5
9
  import AbstractService from "./abstract.ts";
@@ -7,7 +11,7 @@ import AbstractService from "./abstract.ts";
7
11
  export class CustomObjectService extends AbstractService {
8
12
  public repository: CustomObjectRepository;
9
13
 
10
- constructor(parent: Router, repository: CustomObjectRepository) {
14
+ constructor(parent: FastifyInstance, repository: CustomObjectRepository) {
11
15
  super(parent);
12
16
  this.repository = repository;
13
17
  }
@@ -16,76 +20,140 @@ export class CustomObjectService extends AbstractService {
16
20
  return "custom-objects";
17
21
  }
18
22
 
19
- extraRoutes(router: Router) {
20
- router.get("/:container", this.getWithContainer.bind(this));
21
- router.get("/:container/:key", this.getWithContainerAndKey.bind(this));
22
- router.post("/:container/:key", this.createWithContainerAndKey.bind(this));
23
- router.delete(
24
- "/:container/:key",
25
- this.deleteWithContainerAndKey.bind(this),
23
+ registerRoutes(parent: FastifyInstance) {
24
+ const basePath = this.getBasePath();
25
+ parent.register(
26
+ (instance, opts, done) => {
27
+ // Custom object specific routes
28
+ instance.get(
29
+ "/:container/:key",
30
+ this.getWithContainerAndKey.bind(this),
31
+ );
32
+ instance.post(
33
+ "/:container/:key",
34
+ this.createWithContainerAndKey.bind(this),
35
+ );
36
+ instance.delete(
37
+ "/:container/:key",
38
+ this.deleteWithContainerAndKey.bind(this),
39
+ );
40
+
41
+ // Standard routes, but use /:container instead of /:id for GET
42
+ // to avoid duplicate parametric route conflict in Fastify.
43
+ // In Express, /:container was registered first and shadowed /:id.
44
+ instance.get("/", this.get.bind(this));
45
+ instance.get("/key=:key", this.getWithKey.bind(this));
46
+ instance.get("/:container", this.getWithContainer.bind(this));
47
+
48
+ instance.delete("/key=:key", this.deleteWithKey.bind(this));
49
+ instance.delete("/:id", this.deleteWithId.bind(this));
50
+
51
+ instance.post("/", this.post.bind(this));
52
+ instance.post("/key=:key", this.postWithKey.bind(this));
53
+ instance.post("/:id", this.postWithId.bind(this));
54
+
55
+ done();
56
+ },
57
+ { prefix: `/${basePath}` },
26
58
  );
27
59
  }
28
60
 
29
- getWithContainer(request: Request, response: Response) {
30
- const limit = this._parseParam(request.query.limit);
31
- const offset = this._parseParam(request.query.offset);
61
+ async getWithContainer(
62
+ request: FastifyRequest<{
63
+ Params: Record<string, string>;
64
+ Querystring: Record<string, any>;
65
+ }>,
66
+ reply: FastifyReply,
67
+ ) {
68
+ const params = request.params;
69
+ const query = request.query;
70
+ const limit = this._parseParam(query.limit);
71
+ const offset = this._parseParam(query.offset);
32
72
 
33
- const result = this.repository.queryWithContainer(
73
+ const result = await this.repository.queryWithContainer(
34
74
  getRepositoryContext(request),
35
- request.params.container,
75
+ params.container,
36
76
  {
37
- expand: this._parseParam(request.query.expand),
38
- where: this._parseParam(request.query.where),
77
+ expand: this._parseParam(query.expand),
78
+ where: this._parseParam(query.where),
39
79
  limit: limit !== undefined ? Number(limit) : undefined,
40
80
  offset: offset !== undefined ? Number(offset) : undefined,
41
81
  },
42
82
  );
43
83
 
44
- response.status(200).send(result);
84
+ return reply.status(200).send(result);
45
85
  }
46
86
 
47
- getWithContainerAndKey(request: Request, response: Response) {
48
- const result = this.repository.getWithContainerAndKey(
87
+ async getWithContainerAndKey(
88
+ request: FastifyRequest<{ Params: Record<string, string> }>,
89
+ reply: FastifyReply,
90
+ ) {
91
+ const params = request.params;
92
+ const result = await this.repository.getWithContainerAndKey(
49
93
  getRepositoryContext(request),
50
- request.params.container,
51
- request.params.key,
94
+ params.container,
95
+ params.key,
52
96
  );
53
97
 
54
98
  if (!result) {
55
- response.status(404).send({ statusCode: 404 });
56
- return;
99
+ throw new CommercetoolsError<ResourceNotFoundError>(
100
+ {
101
+ code: "ResourceNotFound",
102
+ message: `The CustomObject with container '${params.container}' and key '${params.key}' was not found.`,
103
+ },
104
+ 404,
105
+ );
57
106
  }
58
- response.status(200).send(result);
107
+ return reply.status(200).send(result);
59
108
  }
60
109
 
61
- createWithContainerAndKey(request: Request, response: Response) {
110
+ async createWithContainerAndKey(
111
+ request: FastifyRequest<{
112
+ Params: Record<string, string>;
113
+ Body: CustomObjectDraft;
114
+ }>,
115
+ reply: FastifyReply,
116
+ ) {
117
+ const params = request.params;
62
118
  const draft: CustomObjectDraft = {
63
119
  ...request.body,
64
- key: request.params.key,
65
- container: request.params.container,
120
+ key: params.key,
121
+ container: params.container,
66
122
  };
67
123
 
68
- const result = this.repository.create(getRepositoryContext(request), draft);
69
- response.status(200).send(result);
124
+ const result = await this.repository.create(
125
+ getRepositoryContext(request),
126
+ draft,
127
+ );
128
+ return reply.status(200).send(result);
70
129
  }
71
130
 
72
- deleteWithContainerAndKey(request: Request, response: Response) {
73
- const current = this.repository.getWithContainerAndKey(
131
+ async deleteWithContainerAndKey(
132
+ request: FastifyRequest<{ Params: Record<string, string> }>,
133
+ reply: FastifyReply,
134
+ ) {
135
+ const params = request.params;
136
+ const current = await this.repository.getWithContainerAndKey(
74
137
  getRepositoryContext(request),
75
- request.params.container,
76
- request.params.key,
138
+ params.container,
139
+ params.key,
77
140
  );
78
141
 
79
142
  if (!current) {
80
- response.status(404).send({ statusCode: 404 });
81
- return;
143
+ throw new CommercetoolsError<ResourceNotFoundError>(
144
+ {
145
+ code: "ResourceNotFound",
146
+ message: `The CustomObject with container '${params.container}' and key '${params.key}' was not found.`,
147
+ },
148
+ 404,
149
+ );
82
150
  }
83
151
 
84
- const result = this.repository.delete(
152
+ const result = await this.repository.delete(
85
153
  getRepositoryContext(request),
86
154
  current.id,
87
155
  );
88
156
 
89
- response.status(200).send(result);
157
+ return reply.status(200).send(result);
90
158
  }
91
159
  }
@@ -1,85 +1,80 @@
1
- import type { CustomerGroupDraft } from "@commercetools/platform-sdk";
2
- import supertest from "supertest";
3
1
  import { describe, expect, test } from "vitest";
2
+ import { customerGroupDraftFactory } 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("CustomerGroup", () => {
8
+ const customerGroupDraft = customerGroupDraftFactory(ctMock);
9
+
9
10
  test("Create customer group", async () => {
10
- const draft: CustomerGroupDraft = {
11
+ const draft = customerGroupDraft.build({
11
12
  key: "premium-customers",
12
13
  groupName: "Premium Customers",
13
- };
14
- const response = await supertest(ctMock.app)
15
- .post("/dummy/customer-groups")
16
- .send(draft);
14
+ });
17
15
 
18
- expect(response.status).toBe(201);
16
+ const response = await ctMock.app.inject({
17
+ method: "POST",
18
+ url: "/dummy/customer-groups",
19
+ payload: draft,
20
+ });
19
21
 
20
- expect(response.body).toEqual({
22
+ expect(response.statusCode).toBe(201);
23
+ expect(response.json()).toEqual({
21
24
  createdAt: expect.anything(),
25
+ createdBy: expect.anything(),
22
26
  id: expect.anything(),
23
27
  key: "premium-customers",
24
28
  lastModifiedAt: expect.anything(),
29
+ lastModifiedBy: expect.anything(),
25
30
  name: "Premium Customers",
26
31
  version: 1,
27
32
  });
28
33
  });
29
34
 
30
35
  test("Get customer group", async () => {
31
- const draft: CustomerGroupDraft = {
36
+ const customerGroup = await customerGroupDraft.create({
32
37
  key: "test-group",
33
38
  groupName: "Test Group",
34
- };
35
- const createResponse = await supertest(ctMock.app)
36
- .post("/dummy/customer-groups")
37
- .send(draft);
38
-
39
- expect(createResponse.status).toBe(201);
39
+ });
40
40
 
41
- const response = await supertest(ctMock.app).get(
42
- `/dummy/customer-groups/${createResponse.body.id}`,
43
- );
41
+ const response = await ctMock.app.inject({
42
+ method: "GET",
43
+ url: `/dummy/customer-groups/${customerGroup.id}`,
44
+ });
44
45
 
45
- expect(response.status).toBe(200);
46
- expect(response.body).toEqual(createResponse.body);
46
+ expect(response.statusCode).toBe(200);
47
+ expect(response.json()).toEqual(customerGroup);
47
48
  });
48
49
 
49
50
  test("Get customer group by key", async () => {
50
- const draft: CustomerGroupDraft = {
51
+ const customerGroup = await customerGroupDraft.create({
51
52
  key: "key-group",
52
53
  groupName: "Key Group",
53
- };
54
- const createResponse = await supertest(ctMock.app)
55
- .post("/dummy/customer-groups")
56
- .send(draft);
57
-
58
- expect(createResponse.status).toBe(201);
54
+ });
59
55
 
60
- const response = await supertest(ctMock.app).get(
61
- "/dummy/customer-groups/key=key-group",
62
- );
56
+ const response = await ctMock.app.inject({
57
+ method: "GET",
58
+ url: "/dummy/customer-groups/key=key-group",
59
+ });
63
60
 
64
- expect(response.status).toBe(200);
65
- expect(response.body).toEqual(createResponse.body);
61
+ expect(response.statusCode).toBe(200);
62
+ expect(response.json()).toEqual(customerGroup);
66
63
  });
67
64
 
68
65
  test("Query customer groups", async () => {
69
- const draft: CustomerGroupDraft = {
66
+ const customerGroup = await customerGroupDraft.create({
70
67
  key: "query-group",
71
68
  groupName: "Query Group",
72
- };
73
- const createResponse = await supertest(ctMock.app)
74
- .post("/dummy/customer-groups")
75
- .send(draft);
76
-
77
- expect(createResponse.status).toBe(201);
69
+ });
78
70
 
79
- const response = await supertest(ctMock.app).get("/dummy/customer-groups");
71
+ const response = await ctMock.app.inject({
72
+ method: "GET",
73
+ url: "/dummy/customer-groups",
74
+ });
80
75
 
81
- expect(response.status).toBe(200);
82
- expect(response.body.count).toBeGreaterThan(0);
83
- expect(response.body.results).toContainEqual(createResponse.body);
76
+ expect(response.statusCode).toBe(200);
77
+ expect(response.json().count).toBeGreaterThan(0);
78
+ expect(response.json().results).toContainEqual(customerGroup);
84
79
  });
85
80
  });
@@ -1,11 +1,11 @@
1
- import type { Router } from "express";
1
+ import type { FastifyInstance } from "fastify";
2
2
  import type { CustomerGroupRepository } from "../repositories/customer-group.ts";
3
3
  import AbstractService from "./abstract.ts";
4
4
 
5
5
  export class CustomerGroupService extends AbstractService {
6
6
  public repository: CustomerGroupRepository;
7
7
 
8
- constructor(parent: Router, repository: CustomerGroupRepository) {
8
+ constructor(parent: FastifyInstance, repository: CustomerGroupRepository) {
9
9
  super(parent);
10
10
  this.repository = repository;
11
11
  }