@labdigital/commercetools-mock 2.18.0 → 2.18.2

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.18.0",
3
+ "version": "2.18.2",
4
4
  "license": "MIT",
5
5
  "author": "Michael van Tellingen",
6
6
  "type": "module",
@@ -27,7 +27,9 @@
27
27
  "lodash.isequal": "^4.5.0",
28
28
  "morgan": "^1.10.0",
29
29
  "msw": "^2.2.1",
30
- "uuid": "^9.0.1"
30
+ "uuid": "^9.0.1",
31
+ "zod": "^3.22.4",
32
+ "zod-validation-error": "^3.0.2"
31
33
  },
32
34
  "devDependencies": {
33
35
  "@changesets/changelog-github": "^0.5.0",
package/src/ctMock.ts CHANGED
@@ -2,7 +2,7 @@ import express, { NextFunction, Request, Response } from "express";
2
2
  import inject from "light-my-request";
3
3
  import morgan from "morgan";
4
4
  import { http, HttpResponse } from "msw";
5
- import { setupServer, SetupServer } from "msw/node";
5
+ import { setupServer, SetupServer, SetupServerApi } from "msw/node";
6
6
  import { DEFAULT_API_HOSTNAME, DEFAULT_AUTH_HOSTNAME } from "./constants";
7
7
  import { CommercetoolsError } from "./exceptions";
8
8
  import { copyHeaders } from "./lib/proxy";
@@ -185,7 +185,7 @@ export class CommercetoolsMock {
185
185
  // registerHandlers is an alternative way to work with commercetools-mock, it
186
186
  // allows you to manage msw server yourself and register the handlers needed
187
187
  // for commercetools-mock to work.
188
- public registerHandlers(server: SetupServer) {
188
+ public registerHandlers(server: SetupServerApi) {
189
189
  const app = this.app;
190
190
  server.use(
191
191
  http.post(`${this.options.authHost}/oauth/*`, async ({ request }) => {
@@ -26,7 +26,7 @@ import {
26
26
  export class ProjectRepository extends AbstractRepository<Project> {
27
27
  constructor(storage: AbstractStorage) {
28
28
  super(storage);
29
- this.actions = new ProjectUpdateHandler(this._storage);
29
+ this.actions = new ProjectUpdateHandler(storage);
30
30
  }
31
31
 
32
32
  get(context: RepositoryContext): Project | null {
@@ -0,0 +1,12 @@
1
+ import { z } from "zod";
2
+
3
+ const UpdateActionSchema = z
4
+ .object({
5
+ action: z.string(),
6
+ })
7
+ .passthrough();
8
+
9
+ export const updateRequestSchema = z.object({
10
+ version: z.number(),
11
+ actions: z.array(UpdateActionSchema),
12
+ });
@@ -1,6 +1,8 @@
1
1
  import type { Update } from "@commercetools/platform-sdk";
2
2
  import { Router, type Request, type Response } from "express";
3
3
  import { ParsedQs } from "qs";
4
+ import { updateRequestSchema } from "~src/schemas/update-request";
5
+ import { validateData } from "~src/validate";
4
6
  import { queryParamsArray } from "../helpers";
5
7
  import { AbstractResourceRepository } from "../repositories/abstract";
6
8
  import { getRepositoryContext } from "../repositories/helpers";
@@ -119,7 +121,10 @@ export default abstract class AbstractService {
119
121
  }
120
122
 
121
123
  postWithId(request: Request, response: Response) {
122
- const updateRequest: Update = request.body;
124
+ const updateRequest = validateData<Update>(
125
+ request.body,
126
+ updateRequestSchema,
127
+ );
123
128
  const resource = this.repository.get(
124
129
  getRepositoryContext(request),
125
130
  request.params["id"],
@@ -140,7 +145,11 @@ export default abstract class AbstractService {
140
145
  }
141
146
 
142
147
  postWithKey(request: Request, response: Response) {
143
- const updateRequest: Update = request.body;
148
+ const updateRequest = validateData<Update>(
149
+ request.body,
150
+ updateRequestSchema,
151
+ );
152
+
144
153
  const resource = this.repository.getByKey(
145
154
  getRepositoryContext(request),
146
155
  request.params["key"],
@@ -148,6 +157,7 @@ export default abstract class AbstractService {
148
157
  if (!resource) {
149
158
  return response.status(404).send("Not found");
150
159
  }
160
+
151
161
  const updatedResource = this.repository.processUpdateActions(
152
162
  getRepositoryContext(request),
153
163
  resource,
@@ -1,5 +1,7 @@
1
1
  import { Update } from "@commercetools/platform-sdk";
2
2
  import { Request, Response, Router } from "express";
3
+ import { updateRequestSchema } from "~src/schemas/update-request";
4
+ import { validateData } from "~src/validate";
3
5
  import { hashPassword } from "../lib/password";
4
6
  import { getRepositoryContext } from "../repositories/helpers";
5
7
  import { MyCustomerRepository } from "../repositories/my-customer";
@@ -51,7 +53,10 @@ export class MyCustomerService extends AbstractService {
51
53
  if (!resource) {
52
54
  return response.status(404).send("Not found");
53
55
  }
54
- const updateRequest: Update = request.body;
56
+ const updateRequest = validateData<Update>(
57
+ request.body,
58
+ updateRequestSchema,
59
+ );
55
60
  const updatedResource = this.repository.processUpdateActions(
56
61
  getRepositoryContext(request),
57
62
  resource,
@@ -49,4 +49,9 @@ describe("Project", () => {
49
49
  trialUntil: "2018-12",
50
50
  } as Project);
51
51
  });
52
+
53
+ test("Post empty update ", async () => {
54
+ const response = await supertest(ctMock.app).post("/dummy/");
55
+ expect(response.statusCode).toBe(400);
56
+ });
52
57
  });
@@ -1,5 +1,7 @@
1
- import type { Update } from "@commercetools/platform-sdk";
1
+ import { Update } from "@commercetools/platform-sdk";
2
2
  import { Request, Response, Router } from "express";
3
+ import { updateRequestSchema } from "~src/schemas/update-request";
4
+ import { validateData } from "~src/validate";
3
5
  import { getRepositoryContext } from "../repositories/helpers";
4
6
  import { ProjectRepository } from "../repositories/project";
5
7
 
@@ -22,7 +24,10 @@ export class ProjectService {
22
24
  }
23
25
 
24
26
  post(request: Request, response: Response) {
25
- const updateRequest: Update = request.body;
27
+ const updateRequest = validateData<Update>(
28
+ request.body,
29
+ updateRequestSchema,
30
+ );
26
31
  const project = this.repository.get(getRepositoryContext(request));
27
32
 
28
33
  if (!project) {
@@ -0,0 +1,18 @@
1
+ import { InvalidJsonInputError } from "@commercetools/platform-sdk";
2
+ import { z } from "zod";
3
+ import { fromZodError } from "zod-validation-error";
4
+ import { CommercetoolsError } from "./exceptions";
5
+
6
+ export const validateData = <T>(data: any, schema: z.AnyZodObject) => {
7
+ try {
8
+ schema.parse(data);
9
+ return data as T;
10
+ } catch (err: any) {
11
+ const validationError = fromZodError(err);
12
+ throw new CommercetoolsError<InvalidJsonInputError>({
13
+ code: "InvalidJsonInput",
14
+ message: "Request body does not contain valid JSON.",
15
+ detailedErrorMessage: validationError.toString(),
16
+ });
17
+ }
18
+ };