@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
@@ -2,63 +2,71 @@ import type {
2
2
  Customer,
3
3
  CustomerChangePassword,
4
4
  CustomerToken,
5
- MyCustomerDraft,
6
5
  } from "@commercetools/platform-sdk";
7
- import supertest from "supertest";
8
6
  import { afterEach, beforeEach, describe, expect, test } from "vitest";
7
+ import { customerDraftFactory } from "#src/testing/index.ts";
9
8
  import { CommercetoolsMock, getBaseResourceProperties } from "../index.ts";
10
9
  import { hashPassword } from "../lib/password.ts";
11
10
 
12
11
  const ctMock = new CommercetoolsMock();
13
12
 
14
13
  describe("Me", () => {
14
+ const customerFactory = customerDraftFactory(ctMock);
15
+
15
16
  afterEach(() => {
16
17
  ctMock.clear();
17
18
  });
18
19
 
19
20
  test("Create me", async () => {
20
- const draft: MyCustomerDraft = {
21
+ const draft = customerFactory.build({
21
22
  email: "test@example.org",
22
23
  password: "p4ssw0rd",
23
- };
24
+ });
24
25
 
25
- const response = await supertest(ctMock.app)
26
- .post("/dummy/me/signup")
27
- .send(draft);
26
+ const response = await ctMock.app.inject({
27
+ method: "POST",
28
+ url: "/dummy/me/signup",
29
+ payload: draft,
30
+ });
28
31
 
29
- expect(response.status).toBe(201);
30
- expect(response.body).toEqual({
32
+ expect(response.statusCode).toBe(201);
33
+ expect(response.json()).toEqual({
31
34
  customer: {
32
- ...draft,
35
+ email: "test@example.org",
33
36
  password: "cDRzc3cwcmQ=",
34
- lowercaseEmail: draft.email.toLowerCase(),
37
+ lowercaseEmail: "test@example.org",
35
38
  authenticationMode: "Password",
36
39
  version: 1,
37
40
  isEmailVerified: false,
38
- addresses: [],
41
+ addresses: expect.anything(),
39
42
  billingAddressIds: [],
40
43
  shippingAddressIds: [],
41
44
  id: expect.anything(),
42
45
  createdAt: expect.anything(),
46
+ createdBy: expect.anything(),
43
47
  lastModifiedAt: expect.anything(),
48
+ lastModifiedBy: expect.anything(),
44
49
  stores: [],
50
+ customerGroupAssignments: [],
51
+ firstName: "John",
52
+ lastName: "Doe",
45
53
  },
46
54
  });
47
55
  });
48
56
 
49
57
  test("Get me", async () => {
50
- const draft: MyCustomerDraft = {
58
+ const customer = await customerFactory.create({
51
59
  email: "test@example.org",
52
60
  password: "p4ssw0rd",
53
- };
54
- const createResponse = await supertest(ctMock.app)
55
- .post("/dummy/me/signup")
56
- .send(draft);
61
+ });
57
62
 
58
- const response = await supertest(ctMock.app).get("/dummy/me");
63
+ const response = await ctMock.app.inject({
64
+ method: "GET",
65
+ url: "/dummy/me",
66
+ });
59
67
 
60
- expect(response.status).toBe(200);
61
- expect(response.body).toEqual(createResponse.body.customer);
68
+ expect(response.statusCode).toBe(200);
69
+ expect(response.json()).toEqual(customer);
62
70
  });
63
71
  });
64
72
 
@@ -68,7 +76,7 @@ describe("/me", () => {
68
76
  });
69
77
 
70
78
  beforeEach(() => {
71
- ctMock.project("dummy").add("customer", {
79
+ ctMock.project("dummy").unsafeAdd("customer", {
72
80
  id: "123",
73
81
  createdAt: "2021-03-18T14:00:00.000Z",
74
82
  version: 2,
@@ -79,18 +87,26 @@ describe("/me", () => {
79
87
  authenticationMode: "password",
80
88
  custom: { type: { typeId: "type", id: "" }, fields: {} },
81
89
  stores: [],
90
+ shippingAddressIds: [],
91
+ billingAddressIds: [],
92
+ customerGroupAssignments: [],
82
93
  });
83
94
  });
84
95
 
85
96
  test("Get me", async () => {
86
- const response = await supertest(ctMock.app).get("/dummy/me");
97
+ const response = await ctMock.app.inject({
98
+ method: "GET",
99
+ url: "/dummy/me",
100
+ });
87
101
 
88
- expect(response.status).toBe(200);
89
- expect(response.body).toEqual({
102
+ expect(response.statusCode).toBe(200);
103
+ expect(response.json()).toEqual({
90
104
  id: "123",
91
105
  createdAt: "2021-03-18T14:00:00.000Z",
106
+ createdBy: expect.anything(),
92
107
  version: 2,
93
108
  lastModifiedAt: "2021-03-18T14:00:00.000Z",
109
+ lastModifiedBy: expect.anything(),
94
110
  email: "foo@example.org",
95
111
  addresses: [],
96
112
  isEmailVerified: true,
@@ -103,18 +119,26 @@ describe("/me", () => {
103
119
  },
104
120
  },
105
121
  stores: [],
122
+ shippingAddressIds: [],
123
+ billingAddressIds: [],
124
+ customerGroupAssignments: [],
106
125
  });
107
126
  });
108
127
 
109
128
  test("Delete me", async () => {
110
- const response = await supertest(ctMock.app).delete("/dummy/me");
129
+ const response = await ctMock.app.inject({
130
+ method: "DELETE",
131
+ url: "/dummy/me",
132
+ });
111
133
 
112
- expect(response.status).toBe(200);
113
- expect(response.body).toEqual({
134
+ expect(response.statusCode).toBe(200);
135
+ expect(response.json()).toEqual({
114
136
  id: "123",
115
137
  createdAt: "2021-03-18T14:00:00.000Z",
138
+ createdBy: expect.anything(),
116
139
  version: 2,
117
140
  lastModifiedAt: "2021-03-18T14:00:00.000Z",
141
+ lastModifiedBy: expect.anything(),
118
142
  email: "foo@example.org",
119
143
  addresses: [],
120
144
  isEmailVerified: true,
@@ -127,10 +151,16 @@ describe("/me", () => {
127
151
  },
128
152
  },
129
153
  stores: [],
154
+ shippingAddressIds: [],
155
+ billingAddressIds: [],
156
+ customerGroupAssignments: [],
130
157
  });
131
158
 
132
- const newResponse = await supertest(ctMock.app).get("/dummy/me");
133
- expect(newResponse.status).toBe(404);
159
+ const newResponse = await ctMock.app.inject({
160
+ method: "GET",
161
+ url: "/dummy/me",
162
+ });
163
+ expect(newResponse.statusCode).toBe(404);
134
164
  });
135
165
 
136
166
  test("Change my password", async () => {
@@ -144,8 +174,11 @@ describe("/me", () => {
144
174
  authenticationMode: "Password", //default in Commercetools
145
175
  version: 1,
146
176
  stores: [],
177
+ shippingAddressIds: [],
178
+ billingAddressIds: [],
179
+ customerGroupAssignments: [],
147
180
  };
148
- ctMock.project("dummy").add("customer", customer);
181
+ ctMock.project("dummy").unsafeAdd("customer", customer);
149
182
 
150
183
  const draft: CustomerChangePassword = {
151
184
  id: customer.id,
@@ -153,11 +186,13 @@ describe("/me", () => {
153
186
  newPassword: "newP4ssw0rd",
154
187
  currentPassword: "p4ssw0rd",
155
188
  };
156
- const response = await supertest(ctMock.app)
157
- .post("/dummy/me/password")
158
- .send(draft);
189
+ const response = await ctMock.app.inject({
190
+ method: "POST",
191
+ url: "/dummy/me/password",
192
+ payload: draft,
193
+ });
159
194
 
160
- expect(response.status).toBe(200);
195
+ expect(response.statusCode).toBe(200);
161
196
  });
162
197
 
163
198
  test("Fail to change password", async () => {
@@ -167,12 +202,14 @@ describe("/me", () => {
167
202
  newPassword: "newP4ssw0rd",
168
203
  currentPassword: "p4ssw0rd",
169
204
  };
170
- const response = await supertest(ctMock.app)
171
- .post("/dummy/me/password")
172
- .send(draft);
205
+ const response = await ctMock.app.inject({
206
+ method: "POST",
207
+ url: "/dummy/me/password",
208
+ payload: draft,
209
+ });
173
210
 
174
- expect(response.status).toBe(400);
175
- expect(response.body).toEqual({
211
+ expect(response.statusCode).toBe(400);
212
+ expect(response.json()).toEqual({
176
213
  message: "Account with the given credentials not found.",
177
214
  statusCode: 400,
178
215
  errors: [
@@ -195,34 +232,43 @@ describe("/me", () => {
195
232
  authenticationMode: "Password", //default in Commercetools
196
233
  version: 1,
197
234
  stores: [],
235
+ shippingAddressIds: [],
236
+ billingAddressIds: [],
237
+ customerGroupAssignments: [],
198
238
  };
199
- ctMock.project("dummy").add("customer", customer);
239
+ ctMock.project("dummy").unsafeAdd("customer", customer);
200
240
 
201
- const token = await supertest(ctMock.app)
202
- .post("/dummy/customers/password-token")
203
- .send({
241
+ const tokenResponse = await ctMock.app.inject({
242
+ method: "POST",
243
+ url: "/dummy/customers/password-token",
244
+ payload: {
204
245
  email: "user@example.com",
205
- })
206
- .then((response) => response.body as CustomerToken);
246
+ },
247
+ });
248
+ const token = tokenResponse.json() as CustomerToken;
207
249
 
208
- const response = await supertest(ctMock.app)
209
- .post("/dummy/me/password/reset")
210
- .send({
250
+ const response = await ctMock.app.inject({
251
+ method: "POST",
252
+ url: "/dummy/me/password/reset",
253
+ payload: {
211
254
  tokenValue: token.value,
212
255
  newPassword: "somethingNew",
213
- });
214
- expect(response.status).toBe(200);
256
+ },
257
+ });
258
+ expect(response.statusCode).toBe(200);
215
259
  });
216
260
 
217
261
  test("fail reset password flow", async () => {
218
- const response = await supertest(ctMock.app)
219
- .post("/dummy/me/password/reset")
220
- .send({
262
+ const response = await ctMock.app.inject({
263
+ method: "POST",
264
+ url: "/dummy/me/password/reset",
265
+ payload: {
221
266
  tokenValue: "invalid-token",
222
267
  newPassword: "somethingNew",
223
- });
224
- expect(response.status).toBe(400);
225
- expect(response.body).toEqual({
268
+ },
269
+ });
270
+ expect(response.statusCode).toBe(400);
271
+ expect(response.json()).toEqual({
226
272
  message: `The Customer with ID 'Token(invalid-token)' was not found.`,
227
273
  statusCode: 400,
228
274
  errors: [
@@ -245,32 +291,41 @@ describe("/me", () => {
245
291
  authenticationMode: "Password", //default in Commercetools
246
292
  version: 1,
247
293
  stores: [],
294
+ shippingAddressIds: [],
295
+ billingAddressIds: [],
296
+ customerGroupAssignments: [],
248
297
  };
249
- ctMock.project("dummy").add("customer", customer);
298
+ ctMock.project("dummy").unsafeAdd("customer", customer);
250
299
 
251
- const token = await supertest(ctMock.app)
252
- .post("/dummy/customers/email-token")
253
- .send({
300
+ const tokenResponse = await ctMock.app.inject({
301
+ method: "POST",
302
+ url: "/dummy/customers/email-token",
303
+ payload: {
254
304
  id: "customer-uuid",
255
- })
256
- .then((response) => response.body as CustomerToken);
305
+ },
306
+ });
307
+ const token = tokenResponse.json() as CustomerToken;
257
308
 
258
- const response = await supertest(ctMock.app)
259
- .post("/dummy/me/email/confirm")
260
- .send({
309
+ const response = await ctMock.app.inject({
310
+ method: "POST",
311
+ url: "/dummy/me/email/confirm",
312
+ payload: {
261
313
  tokenValue: token.value,
262
- });
263
- expect(response.status).toBe(200);
314
+ },
315
+ });
316
+ expect(response.statusCode).toBe(200);
264
317
  });
265
318
 
266
319
  test("fail verify email flow", async () => {
267
- const response = await supertest(ctMock.app)
268
- .post("/dummy/me/email/confirm")
269
- .send({
320
+ const response = await ctMock.app.inject({
321
+ method: "POST",
322
+ url: "/dummy/me/email/confirm",
323
+ payload: {
270
324
  tokenValue: "invalid-token",
271
- });
272
- expect(response.status).toBe(400);
273
- expect(response.body).toEqual({
325
+ },
326
+ });
327
+ expect(response.statusCode).toBe(400);
328
+ expect(response.json()).toEqual({
274
329
  message: `The Customer with ID 'Token(invalid-token)' was not found.`,
275
330
  statusCode: 400,
276
331
  errors: [
@@ -283,31 +338,41 @@ describe("/me", () => {
283
338
  });
284
339
 
285
340
  test("setCustomField", async () => {
286
- const response = await supertest(ctMock.app)
287
- .post("/dummy/me")
288
- .send({
341
+ const response = await ctMock.app.inject({
342
+ method: "POST",
343
+ url: "/dummy/me",
344
+ payload: {
289
345
  version: 2,
290
346
  actions: [{ action: "setCustomField", name: "foobar", value: true }],
291
- });
292
- expect(response.status).toBe(200);
293
- expect(response.body.version).toBe(3);
294
- expect(response.body.custom.fields.foobar).toBe(true);
347
+ },
348
+ });
349
+ expect(response.statusCode).toBe(200);
350
+ expect(response.json().version).toBe(3);
351
+ expect(response.json().custom.fields.foobar).toBe(true);
295
352
  });
296
353
 
297
354
  test("deleteMe", async () => {
298
- const response = await supertest(ctMock.app).delete("/dummy/me");
299
- expect(response.status).toBe(200);
300
- expect(response.body.id).toBeDefined();
355
+ const response = await ctMock.app.inject({
356
+ method: "DELETE",
357
+ url: "/dummy/me",
358
+ });
359
+ expect(response.statusCode).toBe(200);
360
+ expect(response.json().id).toBeDefined();
301
361
  });
302
362
 
303
363
  test("signIn with invalid credentials", async () => {
304
- const response = await supertest(ctMock.app).post("/dummy/me/login").send({
305
- email: "nonexistent@example.com",
306
- password: "wrongpassword",
364
+ const response = await ctMock.app.inject({
365
+ method: "POST",
366
+ url: "/dummy/me/login",
367
+ payload: {
368
+ email: "nonexistent@example.com",
369
+ password: "wrongpassword",
370
+ },
307
371
  });
308
372
 
309
- expect(response.status).toBe(400);
310
- expect(response.body).toEqual({
373
+ expect(response.statusCode).toBe(400);
374
+ expect(response.json()).toEqual({
375
+ statusCode: 400,
311
376
  message: "Account with the given credentials not found.",
312
377
  errors: [
313
378
  {
@@ -1,6 +1,14 @@
1
- import type { Update } from "@commercetools/platform-sdk";
2
- import type { Request, Response } from "express";
3
- import { Router } from "express";
1
+ import type {
2
+ MyCustomerChangePassword,
3
+ MyCustomerDraft,
4
+ MyCustomerEmailVerify,
5
+ MyCustomerResetPassword,
6
+ MyCustomerSignin,
7
+ ResourceNotFoundError,
8
+ Update,
9
+ } from "@commercetools/platform-sdk";
10
+ import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
11
+ import { CommercetoolsError } from "#src/exceptions.ts";
4
12
  import { updateRequestSchema } from "#src/schemas/update-request.ts";
5
13
  import { validateData } from "#src/validate.ts";
6
14
  import { hashPassword } from "../lib/password.ts";
@@ -11,7 +19,7 @@ import AbstractService from "./abstract.ts";
11
19
  export class MyCustomerService extends AbstractService {
12
20
  public repository: MyCustomerRepository;
13
21
 
14
- constructor(parent: Router, repository: MyCustomerRepository) {
22
+ constructor(parent: FastifyInstance, repository: MyCustomerRepository) {
15
23
  super(parent);
16
24
  this.repository = repository;
17
25
  }
@@ -20,126 +28,187 @@ export class MyCustomerService extends AbstractService {
20
28
  return "me";
21
29
  }
22
30
 
23
- registerRoutes(parent: Router) {
31
+ registerRoutes(parent: FastifyInstance) {
24
32
  // Overwrite this function to be able to handle /me path.
25
33
  const basePath = this.getBasePath();
26
- const router = Router({ mergeParams: true });
34
+ parent.register(
35
+ (instance, opts, done) => {
36
+ this.extraRoutes(instance);
27
37
 
28
- this.extraRoutes(router);
38
+ instance.get("", this.getMe.bind(this));
39
+ instance.post("", this.updateMe.bind(this));
40
+ instance.delete("", this.deleteMe.bind(this));
29
41
 
30
- router.get("", this.getMe.bind(this));
31
- router.post("", this.updateMe.bind(this));
32
- router.delete("", this.deleteMe.bind(this));
42
+ instance.post("/signup", this.signUp.bind(this));
33
43
 
34
- router.post("/signup", this.signUp.bind(this));
44
+ instance.post("/login", this.signIn.bind(this));
45
+ instance.post("/password", this.changePassword.bind(this));
46
+ instance.post("/password/reset", this.resetPassword.bind(this));
47
+ instance.post("/email/confirm", this.emailConfirm.bind(this));
35
48
 
36
- router.post("/login", this.signIn.bind(this));
37
- router.post("/password", this.changePassword.bind(this));
38
- router.post("/password/reset", this.resetPassword.bind(this));
39
- router.post("/email/confirm", this.emailConfirm.bind(this));
40
-
41
- parent.use(`/${basePath}`, router);
49
+ done();
50
+ },
51
+ { prefix: `/${basePath}` },
52
+ );
42
53
  }
43
54
 
44
- getMe(request: Request, response: Response) {
45
- const resource = this.repository.getMe(getRepositoryContext(request));
55
+ async getMe(
56
+ request: FastifyRequest<{ Params: Record<string, string> }>,
57
+ reply: FastifyReply,
58
+ ) {
59
+ const resource = await this.repository.getMe(getRepositoryContext(request));
46
60
  if (!resource) {
47
- response.status(404).send({ statusCode: 404 });
48
- return;
61
+ throw new CommercetoolsError<ResourceNotFoundError>(
62
+ {
63
+ code: "ResourceNotFound",
64
+ message: "The Resource was not found.",
65
+ },
66
+ 404,
67
+ );
49
68
  }
50
- response.status(200).send(resource);
69
+ return reply.status(200).send(resource);
51
70
  }
52
71
 
53
- updateMe(request: Request, response: Response) {
54
- const resource = this.repository.getMe(getRepositoryContext(request));
72
+ async updateMe(
73
+ request: FastifyRequest<{
74
+ Params: Record<string, string>;
75
+ Querystring: Record<string, any>;
76
+ }>,
77
+ reply: FastifyReply,
78
+ ) {
79
+ const resource = await this.repository.getMe(getRepositoryContext(request));
55
80
 
56
81
  if (!resource) {
57
- response.status(404).send({ statusCode: 404 });
58
- return;
82
+ throw new CommercetoolsError<ResourceNotFoundError>(
83
+ {
84
+ code: "ResourceNotFound",
85
+ message: "The Resource was not found.",
86
+ },
87
+ 404,
88
+ );
59
89
  }
60
90
  const updateRequest = validateData<Update>(
61
91
  request.body,
62
92
  updateRequestSchema,
63
93
  );
64
- const updatedResource = this.repository.processUpdateActions(
94
+ const updatedResource = await this.repository.processUpdateActions(
65
95
  getRepositoryContext(request),
66
96
  resource,
67
97
  updateRequest.version,
68
98
  updateRequest.actions,
69
99
  );
70
100
 
71
- const result = this._expandWithId(request, updatedResource.id);
72
- response.status(200).send(result);
101
+ const result = await this._expandWithId(request, updatedResource.id);
102
+ return reply.status(200).send(result);
73
103
  }
74
104
 
75
- deleteMe(request: Request, response: Response) {
76
- const resource = this.repository.deleteMe(getRepositoryContext(request));
105
+ async deleteMe(
106
+ request: FastifyRequest<{ Params: Record<string, string> }>,
107
+ reply: FastifyReply,
108
+ ) {
109
+ const resource = await this.repository.deleteMe(
110
+ getRepositoryContext(request),
111
+ );
77
112
  if (!resource) {
78
- response.status(404).send({ statusCode: 404 });
79
- return;
113
+ throw new CommercetoolsError<ResourceNotFoundError>(
114
+ {
115
+ code: "ResourceNotFound",
116
+ message: "The Resource was not found.",
117
+ },
118
+ 404,
119
+ );
80
120
  }
81
121
 
82
- response.status(200).send(resource);
122
+ return reply.status(200).send(resource);
83
123
  }
84
124
 
85
- signUp(request: Request, response: Response) {
125
+ async signUp(
126
+ request: FastifyRequest<{
127
+ Params: Record<string, string>;
128
+ Querystring: Record<string, any>;
129
+ Body: MyCustomerDraft;
130
+ }>,
131
+ reply: FastifyReply,
132
+ ) {
86
133
  const draft = request.body;
87
- const resource = this.repository.create(
134
+ const resource = await this.repository.create(
88
135
  getRepositoryContext(request),
89
136
  draft,
90
137
  );
91
- const result = this._expandWithId(request, resource.id);
92
- response.status(this.createStatusCode).send({ customer: result });
138
+ const result = await this._expandWithId(request, resource.id);
139
+ return reply.status(this.createStatusCode).send({ customer: result });
93
140
  }
94
141
 
95
- changePassword(request: Request, response: Response) {
96
- const customer = this.repository.changePassword(
142
+ async changePassword(
143
+ request: FastifyRequest<{
144
+ Params: Record<string, string>;
145
+ Body: MyCustomerChangePassword;
146
+ }>,
147
+ reply: FastifyReply,
148
+ ) {
149
+ const customer = await this.repository.changePassword(
97
150
  getRepositoryContext(request),
98
151
  request.body,
99
152
  );
100
153
 
101
- response.status(200).send(customer);
154
+ return reply.status(200).send(customer);
102
155
  }
103
156
 
104
- resetPassword(request: Request, response: Response) {
105
- const customer = this.repository.passwordReset(
157
+ async resetPassword(
158
+ request: FastifyRequest<{
159
+ Params: Record<string, string>;
160
+ Body: MyCustomerResetPassword;
161
+ }>,
162
+ reply: FastifyReply,
163
+ ) {
164
+ const customer = await this.repository.passwordReset(
106
165
  getRepositoryContext(request),
107
166
  request.body,
108
167
  );
109
168
 
110
- response.status(200).send(customer);
169
+ return reply.status(200).send(customer);
111
170
  }
112
171
 
113
- emailConfirm(request: Request, response: Response) {
114
- const customer = this.repository.confirmEmail(
172
+ async emailConfirm(
173
+ request: FastifyRequest<{
174
+ Params: Record<string, string>;
175
+ Body: MyCustomerEmailVerify;
176
+ }>,
177
+ reply: FastifyReply,
178
+ ) {
179
+ const customer = await this.repository.confirmEmail(
115
180
  getRepositoryContext(request),
116
181
  request.body,
117
182
  );
118
183
 
119
- response.status(200).send(customer);
184
+ return reply.status(200).send(customer);
120
185
  }
121
186
 
122
- signIn(request: Request, response: Response) {
123
- const { email, password } = request.body;
187
+ async signIn(
188
+ request: FastifyRequest<{
189
+ Params: Record<string, string>;
190
+ Body: MyCustomerSignin;
191
+ }>,
192
+ reply: FastifyReply,
193
+ ) {
194
+ const body = request.body;
195
+ const { email, password } = body;
124
196
  const encodedPassword = hashPassword(password);
125
197
 
126
- const result = this.repository.query(getRepositoryContext(request), {
198
+ const result = await this.repository.query(getRepositoryContext(request), {
127
199
  where: [`email = "${email}"`, `password = "${encodedPassword}"`],
128
200
  });
129
201
 
130
202
  if (result.count === 0) {
131
- response.status(400).send({
132
- message: "Account with the given credentials not found.",
133
- errors: [
134
- {
135
- code: "InvalidCredentials",
136
- message: "Account with the given credentials not found.",
137
- },
138
- ],
139
- });
140
- return;
203
+ throw new CommercetoolsError<any>(
204
+ {
205
+ code: "InvalidCredentials",
206
+ message: "Account with the given credentials not found.",
207
+ },
208
+ 400,
209
+ );
141
210
  }
142
211
 
143
- response.status(200).send({ customer: result.results[0] });
212
+ return reply.status(200).send({ customer: result.results[0] });
144
213
  }
145
214
  }