@labdigital/commercetools-mock 2.20.0 → 2.20.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.20.0",
3
+ "version": "2.20.2",
4
4
  "license": "MIT",
5
5
  "author": "Michael van Tellingen",
6
6
  "type": "module",
@@ -49,7 +49,7 @@
49
49
  "@types/uuid": "^9.0.8",
50
50
  "@typescript-eslint/eslint-plugin": "^7.0.2",
51
51
  "@typescript-eslint/parser": "^7.0.2",
52
- "@vitest/coverage-v8": "^1.3.1",
52
+ "@vitest/coverage-v8": "^1.5.0",
53
53
  "esbuild": "^0.20.1",
54
54
  "eslint": "^8.57.0",
55
55
  "eslint-plugin-sort-class-members": "^1.20.0",
@@ -65,12 +65,11 @@
65
65
  "tslib": "^2.6.2",
66
66
  "tsup": "^8.0.2",
67
67
  "typescript": "^5.3.3",
68
- "vitest": "^1.3.1"
68
+ "vitest": "^1.5.0"
69
69
  },
70
- "packageManager": "pnpm@8.6.5",
71
70
  "engines": {
72
71
  "node": ">=18",
73
- "pnpm": ">=8.6.5"
72
+ "pnpm": ">=9.0.2"
74
73
  },
75
74
  "publishConfig": {
76
75
  "access": "public"
@@ -53,7 +53,7 @@ export abstract class AbstractRepository<R extends BaseResource | Project> {
53
53
  resource: R,
54
54
  ): void;
55
55
 
56
- abstract postProcessResource(resource: any): any;
56
+ abstract postProcessResource(context: RepositoryContext, resource: any): any;
57
57
 
58
58
  processUpdateActions(
59
59
  context: RepositoryContext,
@@ -78,7 +78,7 @@ export abstract class AbstractRepository<R extends BaseResource | Project> {
78
78
  this.saveUpdate(context, version, updatedResource);
79
79
  }
80
80
 
81
- const result = this.postProcessResource(updatedResource);
81
+ const result = this.postProcessResource(context, updatedResource);
82
82
  if (!result) {
83
83
  throw new Error("invalid post process action");
84
84
  }
@@ -113,7 +113,9 @@ export abstract class AbstractResourceRepository<
113
113
  id,
114
114
  params,
115
115
  );
116
- return resource ? this.postProcessResource(resource) : null;
116
+ return resource
117
+ ? this.postProcessResource(context, resource, params)
118
+ : null;
117
119
  }
118
120
 
119
121
  get(
@@ -127,7 +129,9 @@ export abstract class AbstractResourceRepository<
127
129
  id,
128
130
  params,
129
131
  );
130
- return resource ? this.postProcessResource(resource) : null;
132
+ return resource
133
+ ? this.postProcessResource(context, resource, params)
134
+ : null;
131
135
  }
132
136
 
133
137
  getByKey(
@@ -141,10 +145,16 @@ export abstract class AbstractResourceRepository<
141
145
  key,
142
146
  params,
143
147
  );
144
- return resource ? this.postProcessResource(resource) : null;
148
+ return resource
149
+ ? this.postProcessResource(context, resource, params)
150
+ : null;
145
151
  }
146
152
 
147
- postProcessResource(resource: ResourceMap[T]): ResourceMap[T] {
153
+ postProcessResource(
154
+ context: RepositoryContext,
155
+ resource: ResourceMap[T],
156
+ params?: GetParams,
157
+ ): ResourceMap[T] {
148
158
  return resource;
149
159
  }
150
160
 
@@ -153,9 +163,13 @@ export abstract class AbstractResourceRepository<
153
163
  ...params,
154
164
  });
155
165
 
156
- // @ts-ignore
157
- result.results = result.results.map(this.postProcessResource);
158
- return result;
166
+ const data = result.results.map((r) =>
167
+ this.postProcessResource(context, r as ResourceMap[T]),
168
+ );
169
+ return {
170
+ ...result,
171
+ results: data,
172
+ };
159
173
  }
160
174
 
161
175
  saveNew(
@@ -0,0 +1,92 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { InMemoryStorage } from "~src/storage";
3
+ import { CategoryRepository } from "./index";
4
+
5
+ describe("Order repository", () => {
6
+ const storage = new InMemoryStorage();
7
+ const repository = new CategoryRepository(storage);
8
+
9
+ test("valid ancestors", async () => {
10
+ const root = repository.create(
11
+ { projectKey: "dummy" },
12
+ {
13
+ key: "root",
14
+ slug: {
15
+ en: "root",
16
+ },
17
+ name: {
18
+ en: "root",
19
+ },
20
+ },
21
+ );
22
+
23
+ const level1 = repository.create(
24
+ { projectKey: "dummy" },
25
+ {
26
+ key: "level-1",
27
+ slug: {
28
+ en: "level-1",
29
+ },
30
+ name: {
31
+ en: "level-1",
32
+ },
33
+ parent: {
34
+ id: root.id,
35
+ typeId: "category",
36
+ },
37
+ },
38
+ );
39
+
40
+ const level2 = repository.create(
41
+ { projectKey: "dummy" },
42
+ {
43
+ key: "level-2",
44
+ slug: {
45
+ en: "level-2",
46
+ },
47
+ name: {
48
+ en: "level-2",
49
+ },
50
+ parent: {
51
+ id: level1.id,
52
+ typeId: "category",
53
+ },
54
+ },
55
+ );
56
+
57
+ const level3 = repository.create(
58
+ { projectKey: "dummy" },
59
+ {
60
+ key: "level-3",
61
+ slug: {
62
+ en: "level-3",
63
+ },
64
+ name: {
65
+ en: "level-3",
66
+ },
67
+ parent: {
68
+ id: level2.id,
69
+ typeId: "category",
70
+ },
71
+ },
72
+ );
73
+
74
+ const result = repository.get({ projectKey: "dummy" }, level3.id);
75
+ expect(result?.ancestors).toHaveLength(3);
76
+ expect(result?.ancestors).toEqual([
77
+ { id: level2.id, typeId: "category" },
78
+ { id: level1.id, typeId: "category" },
79
+ { id: root.id, typeId: "category" },
80
+ ]);
81
+
82
+ const expandResult = repository.get({ projectKey: "dummy" }, level3.id, {
83
+ expand: ["ancestors[*]"],
84
+ });
85
+ expect(expandResult?.ancestors).toHaveLength(3);
86
+ expect(expandResult?.ancestors).toEqual([
87
+ { id: level2.id, typeId: "category", obj: level2 },
88
+ { id: level1.id, typeId: "category", obj: level1 },
89
+ { id: root.id, typeId: "category", obj: root },
90
+ ]);
91
+ });
92
+ });
@@ -1,9 +1,16 @@
1
- import type { Category, CategoryDraft } from "@commercetools/platform-sdk";
1
+ import type {
2
+ Category,
3
+ CategoryDraft,
4
+ CategoryReference,
5
+ } from "@commercetools/platform-sdk";
2
6
  import { v4 as uuidv4 } from "uuid";
3
7
  import { getBaseResourceProperties } from "~src/helpers";
8
+ import { parseExpandClause } from "~src/lib/expandParser";
4
9
  import { AbstractStorage } from "~src/storage/abstract";
10
+ import { Writable } from "~src/types";
5
11
  import {
6
12
  AbstractResourceRepository,
13
+ GetParams,
7
14
  type RepositoryContext,
8
15
  } from "../abstract";
9
16
  import { createCustomFields } from "../helpers";
@@ -26,7 +33,7 @@ export class CategoryRepository extends AbstractResourceRepository<"category"> {
26
33
  parent: draft.parent
27
34
  ? { typeId: "category", id: draft.parent.id! }
28
35
  : undefined,
29
- ancestors: [], // TODO
36
+ ancestors: [], // Resolved at runtime
30
37
  assets:
31
38
  draft.assets?.map((d) => ({
32
39
  id: uuidv4(),
@@ -49,4 +56,38 @@ export class CategoryRepository extends AbstractResourceRepository<"category"> {
49
56
  };
50
57
  return this.saveNew(context, resource);
51
58
  }
59
+
60
+ postProcessResource(
61
+ context: RepositoryContext,
62
+ resource: Writable<Category>,
63
+ params?: GetParams,
64
+ ): Category {
65
+ let node: Category = resource;
66
+ const ancestors: CategoryReference[] = [];
67
+
68
+ // TODO: The expand clause here is a hack, the current expand architecture
69
+ // is not able to handle the case for 'dynamic' fields like ancestors which
70
+ // are resolved at runtime. We should do the expand resolution post query
71
+ // execution for all resources
72
+
73
+ const expandClauses = params?.expand?.map(parseExpandClause) ?? [];
74
+ const addExpand = expandClauses?.find(
75
+ (c) => c.element === "ancestors" && c.index === "*",
76
+ );
77
+
78
+ while (node.parent) {
79
+ node = this._storage.getByResourceIdentifier<"category">(
80
+ context.projectKey,
81
+ node.parent,
82
+ );
83
+ ancestors.push({
84
+ typeId: "category",
85
+ id: node.id,
86
+ obj: addExpand ? node : undefined,
87
+ });
88
+ }
89
+
90
+ resource.ancestors = ancestors;
91
+ return resource;
92
+ }
52
93
  }
@@ -35,7 +35,10 @@ export class ExtensionRepository extends AbstractResourceRepository<"extension">
35
35
  return this.saveNew(context, resource);
36
36
  }
37
37
 
38
- postProcessResource(resource: Extension): Extension {
38
+ postProcessResource(
39
+ context: RepositoryContext,
40
+ resource: Extension,
41
+ ): Extension {
39
42
  if (resource) {
40
43
  const extension = resource as Extension;
41
44
  if (
@@ -31,10 +31,10 @@ export class ProjectRepository extends AbstractRepository<Project> {
31
31
 
32
32
  get(context: RepositoryContext): Project | null {
33
33
  const resource = this._storage.getProject(context.projectKey);
34
- return this.postProcessResource(resource);
34
+ return this.postProcessResource(context, resource);
35
35
  }
36
36
 
37
- postProcessResource(resource: Project): Project {
37
+ postProcessResource(context: RepositoryContext, resource: Project): Project {
38
38
  if (resource) {
39
39
  return maskSecretValue(resource, "externalOAuth.authorizationHeader");
40
40
  }
@@ -144,6 +144,8 @@ describe("categories changeParent", () => {
144
144
  typeId: "category",
145
145
  id: category1?.id,
146
146
  });
147
+ expect(changeNameResponse.body.ancestors).toHaveLength(1);
148
+ expect(changeNameResponse.body.ancestors[0].id).toEqual(category1?.id);
147
149
  });
148
150
  });
149
151