@labdigital/commercetools-mock 2.5.0 → 2.7.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/README.md CHANGED
@@ -3,9 +3,16 @@
3
3
  [<img src="https://img.shields.io/npm/v/@labdigital/commercetools-mock">](https://www.npmjs.com/package/@labdigital/commercetools-mock)
4
4
  [![codecov](https://codecov.io/gh/labd/commercetools-node-mock/branch/main/graph/badge.svg?token=muKkNunJ95)](https://codecov.io/gh/labd/commercetools-node-mock)
5
5
 
6
- This library mocks the Commercetools rest api to ease testing of your typescript
7
- codebases interacting with the commercetools api. It uses the same proven approach
8
- as our testing module in the [commercetools Python SDK](https://github.com/labd/commercetools-python-sdk/tree/main/src/commercetools/testing).
6
+ This library mocks the Commercetools rest API to ease testing of your typescript
7
+ codebases interacting with the commercetools api. It uses the same proven
8
+ approach as our testing module in the
9
+ [commercetools Python SDK](https://github.com/labd/commercetools-python-sdk/tree/main/src/commercetools/testing).
10
+
11
+ Since version 2 of this library it is based on [msw](https://mswjs.io/) instead
12
+ of nock. It is now therefore als recommended to manage the msw server yourself
13
+ and use the `registerHandlers` method to register the handlers on this server.
14
+
15
+ This allows you to use the same server for mocking other API's as well.
9
16
 
10
17
  ## Installation
11
18
 
@@ -15,13 +22,15 @@ yarn add --dev @labdigital/commercetools-mock
15
22
 
16
23
  ## Docker image
17
24
 
18
- This codebase is also available as a docker image where it provides a runnable http server exposing the mocked endpoints. See
19
- https://github.com/labd/commercetools-mock-server
25
+ This codebase is also available as a docker image where it provides a runnable
26
+ http server exposing the mocked endpoints. See
27
+ https://hub.docker.com/r/labdigital/commercetools-mock-server
20
28
 
21
29
  ## Example
22
30
 
23
31
  ```typescript
24
32
  import { CommercetoolsMock, getBaseResourceProperties } from '@labdigital/commercetools-mock'
33
+ import { setupServer } from 'msw/node'
25
34
 
26
35
  const ctMock = new CommercetoolsMock({
27
36
  apiHost: 'https://localhost',
@@ -34,7 +43,8 @@ const ctMock = new CommercetoolsMock({
34
43
 
35
44
  describe('A module', () => {
36
45
  beforeAll(() => {
37
- ctMock.start()
46
+ const server = setupServer()
47
+ ctMock.registerHandlers(server)
38
48
 
39
49
  ctMock.project().add('type', {
40
50
  ...getBaseResourceProperties()
@@ -44,6 +54,7 @@ describe('A module', () => {
44
54
  })
45
55
 
46
56
  afterAll(() => {
57
+ server.clearHandlers()
47
58
  ctMock.stop()
48
59
  })
49
60
 
@@ -61,7 +72,9 @@ describe('A module', () => {
61
72
  })
62
73
  ```
63
74
 
64
- ## Adding a resource
75
+ ## Contributing
76
+
77
+ ### Adding a new service
65
78
 
66
79
  Implement the following:
67
80
 
@@ -71,7 +84,7 @@ Implement the following:
71
84
  - Add new service to src/storage.ts InMemoryStorage
72
85
  - Adjust src/types.ts RepositoryMap and possibly serviceTypes
73
86
 
74
- ## Releasing
87
+ ### Releasing
75
88
 
76
89
  This codebases use [@changesets](https://github.com/changesets/changesets) for release and version management
77
90
 
package/dist/index.cjs CHANGED
@@ -6031,6 +6031,7 @@ var createRepositories = (storage) => ({
6031
6031
  "my-order": new MyOrderRepository(storage),
6032
6032
  "my-customer": new CustomerRepository(storage),
6033
6033
  "my-payment": new PaymentRepository(storage),
6034
+ "my-shopping-list": new ShoppingListRepository(storage),
6034
6035
  product: new ProductRepository(storage),
6035
6036
  "product-type": new ProductTypeRepository(storage),
6036
6037
  "product-discount": new ProductDiscountRepository(storage),
@@ -6486,6 +6487,7 @@ var MyCustomerService = class extends AbstractService {
6486
6487
  const router = (0, import_express4.Router)({ mergeParams: true });
6487
6488
  this.extraRoutes(router);
6488
6489
  router.get("", this.getMe.bind(this));
6490
+ router.post("", this.updateMe.bind(this));
6489
6491
  router.post("/signup", this.signUp.bind(this));
6490
6492
  router.post("/login", this.signIn.bind(this));
6491
6493
  parent.use(`/${basePath}`, router);
@@ -6497,6 +6499,21 @@ var MyCustomerService = class extends AbstractService {
6497
6499
  }
6498
6500
  return response.status(200).send(resource);
6499
6501
  }
6502
+ updateMe(request, response) {
6503
+ const resource = this.repository.getMe(getRepositoryContext(request));
6504
+ if (!resource) {
6505
+ return response.status(404).send("Not found");
6506
+ }
6507
+ const updateRequest = request.body;
6508
+ const updatedResource = this.repository.processUpdateActions(
6509
+ getRepositoryContext(request),
6510
+ resource,
6511
+ updateRequest.version,
6512
+ updateRequest.actions
6513
+ );
6514
+ const result = this._expandWithId(request, updatedResource.id);
6515
+ return response.status(200).send(result);
6516
+ }
6500
6517
  signUp(request, response) {
6501
6518
  const draft = request.body;
6502
6519
  const resource = this.repository.create(
@@ -6563,6 +6580,18 @@ var MyPaymentService = class extends AbstractService {
6563
6580
  }
6564
6581
  };
6565
6582
 
6583
+ // src/services/my-shopping-list.ts
6584
+ var MyShoppingListService = class extends AbstractService {
6585
+ repository;
6586
+ constructor(parent, repository) {
6587
+ super(parent);
6588
+ this.repository = repository;
6589
+ }
6590
+ getBasePath() {
6591
+ return "me/shopping-lists";
6592
+ }
6593
+ };
6594
+
6566
6595
  // src/services/order.ts
6567
6596
  var OrderService = class extends AbstractService {
6568
6597
  repository;
@@ -6850,6 +6879,10 @@ var createServices = (router, repos) => ({
6850
6879
  "my-order": new MyOrderService(router, repos["my-order"]),
6851
6880
  "my-customer": new MyCustomerService(router, repos["my-customer"]),
6852
6881
  "my-payment": new MyPaymentService(router, repos["my-payment"]),
6882
+ "my-shopping-list": new MyShoppingListService(
6883
+ router,
6884
+ repos["my-shopping-list"]
6885
+ ),
6853
6886
  "shipping-method": new ShippingMethodService(
6854
6887
  router,
6855
6888
  repos["shipping-method"]
@@ -6921,7 +6954,6 @@ var CommercetoolsMock = class {
6921
6954
  this._mswServer = void 0;
6922
6955
  }
6923
6956
  clear() {
6924
- this._mswServer?.resetHandlers();
6925
6957
  this._storage.clear();
6926
6958
  }
6927
6959
  project(projectKey) {
@@ -6992,22 +7024,17 @@ var CommercetoolsMock = class {
6992
7024
  });
6993
7025
  return app;
6994
7026
  }
6995
- startServer() {
6996
- if (_globalListeners.length > 0) {
6997
- if (this._mswServer !== void 0) {
6998
- throw new Error("Server already started");
6999
- } else {
7000
- console.warn("Server wasn't stopped properly, clearing");
7001
- _globalListeners.forEach((listener) => listener.close());
7002
- }
7003
- }
7004
- const server = this.app;
7005
- this._mswServer = (0, import_node.setupServer)(
7027
+ // registerHandlers is an alternative way to work with commercetools-mock, it
7028
+ // allows you to manage msw server yourself and register the handlers needed
7029
+ // for commercetools-mock to work.
7030
+ registerHandlers(server) {
7031
+ const app = this.app;
7032
+ server.use(
7006
7033
  import_msw.http.post(`${this.options.authHost}/oauth/*`, async ({ request }) => {
7007
7034
  const body = await request.text();
7008
7035
  const url = new URL(request.url);
7009
7036
  const headers = copyHeaders(request.headers);
7010
- const res = await (0, import_light_my_request.default)(server).post(url.pathname + "?" + url.searchParams.toString()).body(body).headers(headers).end();
7037
+ const res = await (0, import_light_my_request.default)(app).post(url.pathname + "?" + url.searchParams.toString()).body(body).headers(headers).end();
7011
7038
  return new import_msw.HttpResponse(res.body, {
7012
7039
  status: res.statusCode,
7013
7040
  headers: mapHeaderType(res.headers)
@@ -7017,7 +7044,7 @@ var CommercetoolsMock = class {
7017
7044
  const body = await request.text();
7018
7045
  const url = new URL(request.url);
7019
7046
  const headers = copyHeaders(request.headers);
7020
- const res = await (0, import_light_my_request.default)(server).get(url.pathname + "?" + url.searchParams.toString()).body(body).headers(headers).end();
7047
+ const res = await (0, import_light_my_request.default)(app).get(url.pathname + "?" + url.searchParams.toString()).body(body).headers(headers).end();
7021
7048
  if (res.statusCode === 200) {
7022
7049
  const parsedBody = JSON.parse(res.body);
7023
7050
  const resultCount = "count" in parsedBody ? parsedBody.count : Object.keys(parsedBody).length;
@@ -7035,7 +7062,7 @@ var CommercetoolsMock = class {
7035
7062
  const body = await request.text();
7036
7063
  const url = new URL(request.url);
7037
7064
  const headers = copyHeaders(request.headers);
7038
- const res = await (0, import_light_my_request.default)(server).get(url.pathname + "?" + url.searchParams.toString()).body(body).headers(headers).end();
7065
+ const res = await (0, import_light_my_request.default)(app).get(url.pathname + "?" + url.searchParams.toString()).body(body).headers(headers).end();
7039
7066
  return new import_msw.HttpResponse(res.body, {
7040
7067
  status: res.statusCode,
7041
7068
  headers: mapHeaderType(res.headers)
@@ -7045,7 +7072,7 @@ var CommercetoolsMock = class {
7045
7072
  const body = await request.text();
7046
7073
  const url = new URL(request.url);
7047
7074
  const headers = copyHeaders(request.headers);
7048
- const res = await (0, import_light_my_request.default)(server).post(url.pathname + "?" + url.searchParams.toString()).body(body).headers(headers).end();
7075
+ const res = await (0, import_light_my_request.default)(app).post(url.pathname + "?" + url.searchParams.toString()).body(body).headers(headers).end();
7049
7076
  return new import_msw.HttpResponse(res.body, {
7050
7077
  status: res.statusCode,
7051
7078
  headers: mapHeaderType(res.headers)
@@ -7055,14 +7082,26 @@ var CommercetoolsMock = class {
7055
7082
  const body = await request.text();
7056
7083
  const url = new URL(request.url);
7057
7084
  const headers = copyHeaders(request.headers);
7058
- const res = await (0, import_light_my_request.default)(server).delete(url.pathname + "?" + url.searchParams.toString()).body(body).headers(headers).end();
7085
+ const res = await (0, import_light_my_request.default)(app).delete(url.pathname + "?" + url.searchParams.toString()).body(body).headers(headers).end();
7059
7086
  return new import_msw.HttpResponse(res.body, {
7060
7087
  status: res.statusCode,
7061
7088
  headers: mapHeaderType(res.headers)
7062
7089
  });
7063
7090
  })
7064
7091
  );
7065
- this._mswServer.listen({
7092
+ }
7093
+ startServer() {
7094
+ if (_globalListeners.length > 0) {
7095
+ if (this._mswServer !== void 0) {
7096
+ throw new Error("Server already started");
7097
+ } else {
7098
+ console.warn("Server wasn't stopped properly, clearing");
7099
+ _globalListeners.forEach((listener) => listener.close());
7100
+ }
7101
+ }
7102
+ const server = (0, import_node.setupServer)();
7103
+ this.registerHandlers(server);
7104
+ server.listen({
7066
7105
  // We need to allow requests done by supertest
7067
7106
  onUnhandledRequest: (request, print) => {
7068
7107
  const url = new URL(request.url);
@@ -7072,7 +7111,8 @@ var CommercetoolsMock = class {
7072
7111
  print.error();
7073
7112
  }
7074
7113
  });
7075
- _globalListeners.push(this._mswServer);
7114
+ _globalListeners.push(server);
7115
+ this._mswServer = server;
7076
7116
  }
7077
7117
  };
7078
7118
  // Annotate the CommonJS export names for ESM import in node: