@labdigital/commercetools-mock 2.33.0 → 2.34.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@labdigital/commercetools-mock",
3
- "version": "2.33.0",
3
+ "version": "2.34.0",
4
4
  "license": "MIT",
5
5
  "author": "Michael van Tellingen",
6
6
  "type": "module",
@@ -23,7 +23,6 @@
23
23
  "body-parser": "^1.20.2",
24
24
  "deep-equal": "^2.2.3",
25
25
  "express": "^4.19.2",
26
- "light-my-request": "^5.11.1",
27
26
  "lodash.isequal": "^4.5.0",
28
27
  "morgan": "^1.10.0",
29
28
  "msw": "^2.2.1",
package/src/ctMock.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import express, { NextFunction, Request, Response } from "express";
2
- import inject from "light-my-request";
3
2
  import morgan from "morgan";
4
3
  import { http, HttpResponse } from "msw";
5
4
  import { setupServer, SetupServer, SetupServerApi } from "msw/node";
5
+ import supertest from "supertest";
6
6
  import { DEFAULT_API_HOSTNAME, DEFAULT_AUTH_HOSTNAME } from "./constants";
7
7
  import { CommercetoolsError } from "./exceptions";
8
8
  import { copyHeaders } from "./lib/proxy";
@@ -193,12 +193,12 @@ export class CommercetoolsMock {
193
193
  const url = new URL(request.url);
194
194
  const headers = copyHeaders(request.headers);
195
195
 
196
- const res = await inject(app)
196
+ const res = await supertest(app)
197
197
  .post(url.pathname + "?" + url.searchParams.toString())
198
- .body(body)
199
- .headers(headers)
200
- .end();
201
- return new HttpResponse(res.body, {
198
+ .send(body)
199
+ .set(headers);
200
+
201
+ return new HttpResponse(JSON.stringify(res.body), {
202
202
  status: res.statusCode,
203
203
  headers: mapHeaderType(res.headers),
204
204
  });
@@ -208,11 +208,10 @@ export class CommercetoolsMock {
208
208
  const url = new URL(request.url);
209
209
  const headers = copyHeaders(request.headers);
210
210
 
211
- const res = await inject(app)
211
+ const res = await supertest(app)
212
212
  .get(url.pathname + "?" + url.searchParams.toString())
213
- .body(body)
214
- .headers(headers)
215
- .end();
213
+ .send(body)
214
+ .set(headers);
216
215
 
217
216
  if (res.statusCode === 200) {
218
217
  const parsedBody = JSON.parse(res.body);
@@ -239,12 +238,11 @@ export class CommercetoolsMock {
239
238
  const url = new URL(request.url);
240
239
  const headers = copyHeaders(request.headers);
241
240
 
242
- const res = await inject(app)
241
+ const res = await supertest(app)
243
242
  .get(url.pathname + "?" + url.searchParams.toString())
244
- .body(body)
245
- .headers(headers)
246
- .end();
247
- return new HttpResponse(res.body, {
243
+ .send(body)
244
+ .set(headers);
245
+ return new HttpResponse(JSON.stringify(res.body), {
248
246
  status: res.statusCode,
249
247
  headers: mapHeaderType(res.headers),
250
248
  });
@@ -254,11 +252,10 @@ export class CommercetoolsMock {
254
252
  const url = new URL(request.url);
255
253
  const headers = copyHeaders(request.headers);
256
254
 
257
- const res = await inject(app)
255
+ const res = await supertest(app)
258
256
  .post(url.pathname + "?" + url.searchParams.toString())
259
- .body(body)
260
- .headers(headers)
261
- .end();
257
+ .send(body)
258
+ .set(headers);
262
259
  return new HttpResponse(res.body, {
263
260
  status: res.statusCode,
264
261
  headers: mapHeaderType(res.headers),
@@ -269,11 +266,10 @@ export class CommercetoolsMock {
269
266
  const url = new URL(request.url);
270
267
  const headers = copyHeaders(request.headers);
271
268
 
272
- const res = await inject(app)
269
+ const res = await supertest(app)
273
270
  .delete(url.pathname + "?" + url.searchParams.toString())
274
- .body(body)
275
- .headers(headers)
276
- .end();
271
+ .send(body)
272
+ .set(headers);
277
273
  return new HttpResponse(res.body, {
278
274
  status: res.statusCode,
279
275
  headers: mapHeaderType(res.headers),
package/src/index.test.ts CHANGED
@@ -1,10 +1,16 @@
1
1
  import { type InvalidTokenError } from "@commercetools/platform-sdk";
2
2
  import got from "got";
3
- import { expect, test } from "vitest";
3
+ import { afterEach, expect, test } from "vitest";
4
4
  import { CommercetoolsMock } from "./index";
5
5
 
6
+ let ctMock: CommercetoolsMock;
7
+
8
+ afterEach(() => {
9
+ ctMock.stop();
10
+ });
11
+
6
12
  test("node:fetch client", async () => {
7
- const ctMock = new CommercetoolsMock({
13
+ ctMock = new CommercetoolsMock({
8
14
  enableAuthentication: true,
9
15
  validateCredentials: true,
10
16
  apiHost: "https://localhost",
@@ -44,11 +50,10 @@ test("node:fetch client", async () => {
44
50
  limit: 20,
45
51
  results: [],
46
52
  });
47
- ctMock.stop();
48
53
  });
49
54
 
50
55
  test("got client", async () => {
51
- const ctMock = new CommercetoolsMock({
56
+ ctMock = new CommercetoolsMock({
52
57
  enableAuthentication: true,
53
58
  validateCredentials: true,
54
59
  apiHost: "https://localhost",
@@ -86,11 +91,10 @@ test("got client", async () => {
86
91
  limit: 20,
87
92
  results: [],
88
93
  });
89
- ctMock.stop();
90
94
  });
91
95
 
92
96
  test("Options.validateCredentials: true (error)", async () => {
93
- const ctMock = new CommercetoolsMock({
97
+ ctMock = new CommercetoolsMock({
94
98
  enableAuthentication: true,
95
99
  validateCredentials: true,
96
100
  });
@@ -108,11 +112,10 @@ test("Options.validateCredentials: true (error)", async () => {
108
112
  );
109
113
  expect(response.statusCode).toBe(401);
110
114
  expect(response.body.message).toBe("invalid_token");
111
- ctMock.stop();
112
115
  });
113
116
 
114
117
  test("Options.validateCredentials: false", async () => {
115
- const ctMock = new CommercetoolsMock({
118
+ ctMock = new CommercetoolsMock({
116
119
  enableAuthentication: true,
117
120
  validateCredentials: false,
118
121
  });
@@ -135,7 +138,6 @@ test("Options.validateCredentials: false", async () => {
135
138
  limit: 20,
136
139
  results: [],
137
140
  });
138
- ctMock.stop();
139
141
  });
140
142
 
141
143
  test("Options.enableAuthentication: false", async () => {
@@ -159,11 +161,10 @@ test("Options.enableAuthentication: false", async () => {
159
161
  limit: 20,
160
162
  results: [],
161
163
  });
162
- ctMock.stop();
163
164
  });
164
165
 
165
166
  test("Options.apiHost: is overridden is set", async () => {
166
- const ctMock = new CommercetoolsMock({
167
+ ctMock = new CommercetoolsMock({
167
168
  enableAuthentication: false,
168
169
  validateCredentials: false,
169
170
  apiHost: "http://api.localhost",
@@ -181,11 +182,10 @@ test("Options.apiHost: is overridden is set", async () => {
181
182
  limit: 20,
182
183
  results: [],
183
184
  });
184
- ctMock.stop();
185
185
  });
186
186
 
187
187
  test("Options.authHost: is set", async () => {
188
- const ctMock = new CommercetoolsMock({
188
+ ctMock = new CommercetoolsMock({
189
189
  enableAuthentication: true,
190
190
  validateCredentials: true,
191
191
  authHost: "http://auth.localhost",
@@ -211,7 +211,7 @@ test("Options.authHost: is set", async () => {
211
211
  });
212
212
 
213
213
  test("apiHost mock proxy: querystring", async () => {
214
- const ctMock = new CommercetoolsMock({
214
+ ctMock = new CommercetoolsMock({
215
215
  enableAuthentication: false,
216
216
  validateCredentials: false,
217
217
  apiHost: "http://api.localhost",
@@ -234,5 +234,4 @@ test("apiHost mock proxy: querystring", async () => {
234
234
  limit: 20,
235
235
  results: [],
236
236
  });
237
- ctMock.stop();
238
237
  });
@@ -12,6 +12,7 @@ import {
12
12
  type CartRemoveDiscountCodeAction,
13
13
  type CartRemoveLineItemAction,
14
14
  type CartSetBillingAddressAction,
15
+ type CartSetBillingAddressCustomTypeAction,
15
16
  type CartSetCountryAction,
16
17
  type CartSetCustomFieldAction,
17
18
  type CartSetCustomShippingMethodAction,
@@ -21,6 +22,7 @@ import {
21
22
  type CartSetLineItemShippingDetailsAction,
22
23
  type CartSetLocaleAction,
23
24
  type CartSetShippingAddressAction,
25
+ type CartSetShippingAddressCustomTypeAction,
24
26
  type CartSetShippingMethodAction,
25
27
  type CustomFields,
26
28
  type GeneralError,
@@ -323,6 +325,38 @@ export class CartUpdateHandler
323
325
  );
324
326
  }
325
327
 
328
+ setBillingAddressCustomType(
329
+ context: RepositoryContext,
330
+ resource: Writable<Cart>,
331
+ custom: CartSetBillingAddressCustomTypeAction,
332
+ ) {
333
+ if (!resource.billingAddress) {
334
+ throw new Error("Resource has no billing address");
335
+ }
336
+
337
+ if (!custom.type) {
338
+ resource.billingAddress.custom = undefined;
339
+ return;
340
+ }
341
+
342
+ const resolvedType = this._storage.getByResourceIdentifier<"type">(
343
+ context.projectKey,
344
+ custom.type,
345
+ );
346
+
347
+ if (!resolvedType) {
348
+ throw new Error(`Type ${custom.type} not found`);
349
+ }
350
+
351
+ resource.billingAddress.custom = {
352
+ type: {
353
+ typeId: "type",
354
+ id: resolvedType.id,
355
+ },
356
+ fields: custom.fields || {},
357
+ };
358
+ }
359
+
326
360
  setCountry(
327
361
  context: RepositoryContext,
328
362
  resource: Writable<Cart>,
@@ -503,6 +537,38 @@ export class CartUpdateHandler
503
537
  };
504
538
  }
505
539
 
540
+ setShippingAddressCustomType(
541
+ context: RepositoryContext,
542
+ resource: Writable<Cart>,
543
+ custom: CartSetShippingAddressCustomTypeAction,
544
+ ) {
545
+ if (!resource.shippingAddress) {
546
+ throw new Error("Resource has no shipping address");
547
+ }
548
+
549
+ if (!custom.type) {
550
+ resource.shippingAddress.custom = undefined;
551
+ return;
552
+ }
553
+
554
+ const resolvedType = this._storage.getByResourceIdentifier<"type">(
555
+ context.projectKey,
556
+ custom.type,
557
+ );
558
+
559
+ if (!resolvedType) {
560
+ throw new Error(`Type ${custom.type} not found`);
561
+ }
562
+
563
+ resource.shippingAddress.custom = {
564
+ type: {
565
+ typeId: "type",
566
+ id: resolvedType.id,
567
+ },
568
+ fields: custom.fields || {},
569
+ };
570
+ }
571
+
506
572
  setShippingMethod(
507
573
  context: RepositoryContext,
508
574
  resource: Writable<Cart>,
@@ -605,6 +605,140 @@ describe("Cart Update Actions", () => {
605
605
  expect(response.body.shippingAddress).toEqual(address);
606
606
  });
607
607
 
608
+ test("setBillingAddressCustomType", async () => {
609
+ assert(cart, "cart not created");
610
+
611
+ const address: Address = {
612
+ streetName: "Street name",
613
+ city: "Utrecht",
614
+ country: "NL",
615
+ };
616
+
617
+ const type = await supertest(ctMock.app)
618
+ .post(`/dummy/types`)
619
+ .send({
620
+ key: "my-type",
621
+ name: {
622
+ en: "My Type",
623
+ },
624
+ description: {
625
+ en: "My Type Description",
626
+ },
627
+ fieldDefinitions: [
628
+ {
629
+ name: "foo",
630
+ label: {
631
+ en: "foo",
632
+ },
633
+ required: false,
634
+ type: {
635
+ name: "String",
636
+ },
637
+ inputHint: "SingleLine",
638
+ },
639
+ ],
640
+ })
641
+ .then((x) => x.body);
642
+
643
+ assert(type, "type not created");
644
+
645
+ const response = await supertest(ctMock.app)
646
+ .post(`/dummy/carts/${cart.id}`)
647
+ .send({
648
+ version: 1,
649
+ actions: [
650
+ { action: "setBillingAddress", address },
651
+ {
652
+ action: "setBillingAddressCustomType",
653
+ type: {
654
+ typeId: "type",
655
+ type: "my-type",
656
+ key: "my-type",
657
+ },
658
+ fields: {
659
+ foo: "bar",
660
+ },
661
+ },
662
+ ],
663
+ });
664
+
665
+ expect(response.status).toBe(200);
666
+ expect(response.body.version).toBe(3);
667
+ expect(response.body.billingAddress).toEqual({
668
+ ...address,
669
+ custom: {
670
+ type: { typeId: "type", id: type.id },
671
+ fields: { foo: "bar" },
672
+ },
673
+ });
674
+ });
675
+ test("setShippingAddressCustomType", async () => {
676
+ assert(cart, "cart not created");
677
+
678
+ const address: Address = {
679
+ streetName: "Street name",
680
+ city: "Utrecht",
681
+ country: "NL",
682
+ };
683
+
684
+ const type = await supertest(ctMock.app)
685
+ .post(`/dummy/types`)
686
+ .send({
687
+ key: "my-type",
688
+ name: {
689
+ en: "My Type",
690
+ },
691
+ description: {
692
+ en: "My Type Description",
693
+ },
694
+ fieldDefinitions: [
695
+ {
696
+ name: "foo",
697
+ label: {
698
+ en: "foo",
699
+ },
700
+ required: false,
701
+ type: {
702
+ name: "String",
703
+ },
704
+ inputHint: "SingleLine",
705
+ },
706
+ ],
707
+ })
708
+ .then((x) => x.body);
709
+
710
+ assert(type, "type not created");
711
+
712
+ const response = await supertest(ctMock.app)
713
+ .post(`/dummy/carts/${cart.id}`)
714
+ .send({
715
+ version: 1,
716
+ actions: [
717
+ { action: "setShippingAddress", address },
718
+ {
719
+ action: "setShippingAddressCustomType",
720
+ type: {
721
+ typeId: "type",
722
+ type: "my-type",
723
+ key: "my-type",
724
+ },
725
+ fields: {
726
+ foo: "bar",
727
+ },
728
+ },
729
+ ],
730
+ });
731
+
732
+ expect(response.status).toBe(200);
733
+ expect(response.body.version).toBe(3);
734
+ expect(response.body.shippingAddress).toEqual({
735
+ ...address,
736
+ custom: {
737
+ type: { typeId: "type", id: type.id },
738
+ fields: { foo: "bar" },
739
+ },
740
+ });
741
+ });
608
742
  test("setLineItemShippingDetails", async () => {
609
743
  const product = await supertest(ctMock.app)
610
744
  .post(`/dummy/products`)