@powerhousedao/reactor-api 5.1.0-dev.31 → 5.1.0-dev.33
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/dist/src/graphql/graphql-manager.d.ts.map +1 -1
- package/dist/src/graphql/graphql-manager.js +2 -4
- package/dist/src/graphql/graphql-manager.js.map +1 -1
- package/dist/src/graphql/index.d.ts +0 -1
- package/dist/src/graphql/index.d.ts.map +1 -1
- package/dist/src/graphql/index.js +0 -1
- package/dist/src/graphql/index.js.map +1 -1
- package/dist/src/graphql/reactor/adapters.d.ts +2 -2
- package/dist/src/graphql/reactor/adapters.d.ts.map +1 -1
- package/dist/src/graphql/reactor/adapters.js +2 -2
- package/dist/src/graphql/reactor/adapters.js.map +1 -1
- package/dist/src/graphql/reactor/resolvers.d.ts.map +1 -1
- package/dist/src/graphql/reactor/resolvers.js +4 -6
- package/dist/src/graphql/reactor/resolvers.js.map +1 -1
- package/dist/src/graphql/reactor/subgraph.d.ts.map +1 -1
- package/dist/src/graphql/reactor/subgraph.js +0 -9
- package/dist/src/graphql/reactor/subgraph.js.map +1 -1
- package/dist/src/graphql/reactor/validation.d.ts +4 -4
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +2 -1
- package/dist/src/server.js.map +1 -1
- package/dist/src/tracing.d.ts +2 -108
- package/dist/src/tracing.d.ts.map +1 -1
- package/dist/src/tracing.js +115 -252
- package/dist/src/tracing.js.map +1 -1
- package/dist/test/permissions-integration.test.js +1 -1
- package/dist/test/permissions-integration.test.js.map +1 -1
- package/dist/test/reactor-adapters.test.js +30 -137
- package/dist/test/reactor-adapters.test.js.map +1 -1
- package/dist/test/reactor-resolvers.test.js +157 -970
- package/dist/test/reactor-resolvers.test.js.map +1 -1
- package/dist/test/reactor-subgraph-permissions.test.js +1 -1
- package/dist/test/reactor-subgraph-permissions.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -8
- package/dist/src/graphql/datadog-plugin.d.ts +0 -14
- package/dist/src/graphql/datadog-plugin.d.ts.map +0 -1
- package/dist/src/graphql/datadog-plugin.js +0 -103
- package/dist/src/graphql/datadog-plugin.js.map +0 -1
|
@@ -1,1073 +1,260 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactorBuilder, ReactorClientBuilder, } from "@powerhousedao/reactor";
|
|
2
|
+
import { driveDocumentModelModule } from "document-drive";
|
|
2
3
|
import { documentModelDocumentModelModule, } from "document-model";
|
|
3
|
-
import { beforeEach, describe, expect, it
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
4
5
|
import * as resolvers from "../src/graphql/reactor/resolvers.js";
|
|
6
|
+
const createTestDocument = () => {
|
|
7
|
+
return documentModelDocumentModelModule.utils.createDocument();
|
|
8
|
+
};
|
|
5
9
|
describe("ReactorSubgraph Query Resolvers", () => {
|
|
6
|
-
let
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
execute: vi.fn(),
|
|
21
|
-
executeAsync: vi.fn(),
|
|
22
|
-
rename: vi.fn(),
|
|
23
|
-
addChildren: vi.fn(),
|
|
24
|
-
removeChildren: vi.fn(),
|
|
25
|
-
moveChildren: vi.fn(),
|
|
26
|
-
deleteDocument: vi.fn(),
|
|
27
|
-
deleteDocuments: vi.fn(),
|
|
28
|
-
subscribe: vi.fn(),
|
|
29
|
-
};
|
|
10
|
+
let module;
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
const reactorBuilder = new ReactorBuilder()
|
|
13
|
+
.withDocumentModels([
|
|
14
|
+
driveDocumentModelModule,
|
|
15
|
+
documentModelDocumentModelModule,
|
|
16
|
+
])
|
|
17
|
+
.withFeatures({ legacyStorageEnabled: false });
|
|
18
|
+
module = await new ReactorClientBuilder()
|
|
19
|
+
.withReactorBuilder(reactorBuilder)
|
|
20
|
+
.buildModule();
|
|
21
|
+
});
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
module.reactor.kill();
|
|
30
24
|
});
|
|
31
25
|
describe("documentModels", () => {
|
|
32
26
|
it("should transform document models to GraphQL format", async () => {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
],
|
|
37
|
-
options: {
|
|
38
|
-
cursor: "test-cursor",
|
|
39
|
-
limit: 10,
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
vi.mocked(mockReactorClient.getDocumentModels).mockResolvedValue(mockDocumentModels);
|
|
43
|
-
const result = await resolvers.documentModels(mockReactorClient, {
|
|
44
|
-
namespace: "powerhouse",
|
|
45
|
-
paging: { cursor: "test-cursor", limit: 10 },
|
|
46
|
-
});
|
|
47
|
-
expect(result).toEqual({
|
|
48
|
-
cursor: "test-cursor",
|
|
49
|
-
hasNextPage: false,
|
|
50
|
-
hasPreviousPage: false,
|
|
51
|
-
items: [
|
|
52
|
-
{
|
|
53
|
-
id: "powerhouse/document-model",
|
|
54
|
-
name: "DocumentModel",
|
|
55
|
-
namespace: "DocumentModel",
|
|
56
|
-
specification: mockDocumentModels.results[0].documentModel.global
|
|
57
|
-
.specifications[0],
|
|
58
|
-
version: null,
|
|
59
|
-
},
|
|
60
|
-
],
|
|
61
|
-
totalCount: 1,
|
|
27
|
+
const result = await resolvers.documentModels(module.client, {
|
|
28
|
+
namespace: null,
|
|
29
|
+
paging: { cursor: null, limit: 10 },
|
|
62
30
|
});
|
|
31
|
+
expect(result.items.length).toBeGreaterThan(0);
|
|
32
|
+
expect(result.items[0]).toHaveProperty("id");
|
|
33
|
+
expect(result.items[0]).toHaveProperty("name");
|
|
63
34
|
});
|
|
64
|
-
it("should
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
description: "Description",
|
|
74
|
-
extension: "ext",
|
|
75
|
-
specifications: [],
|
|
76
|
-
},
|
|
77
|
-
local: {},
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
],
|
|
81
|
-
options: { cursor: "", limit: 10 },
|
|
82
|
-
};
|
|
83
|
-
vi.mocked(mockReactorClient.getDocumentModels).mockResolvedValue(mockDocumentModels);
|
|
84
|
-
const result = await resolvers.documentModels(mockReactorClient, {});
|
|
85
|
-
expect(result.items[0].namespace).toBe("custom-namespace");
|
|
35
|
+
it("should filter by namespace", async () => {
|
|
36
|
+
const result = await resolvers.documentModels(module.client, {
|
|
37
|
+
namespace: "powerhouse",
|
|
38
|
+
paging: null,
|
|
39
|
+
});
|
|
40
|
+
expect(result.items.length).toBeGreaterThan(0);
|
|
41
|
+
for (const item of result.items) {
|
|
42
|
+
expect(item.id).toContain("powerhouse/");
|
|
43
|
+
}
|
|
86
44
|
});
|
|
87
45
|
});
|
|
88
46
|
describe("document", () => {
|
|
89
47
|
it("should transform document to GraphQL format with revision list", async () => {
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
documentType: "powerhouse/document-model",
|
|
95
|
-
slug: "test-doc",
|
|
96
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
97
|
-
lastModifiedAtUtcIso: "2024-01-02T00:00:00Z",
|
|
98
|
-
branch: "main",
|
|
99
|
-
sig: {
|
|
100
|
-
publicKey: {},
|
|
101
|
-
nonce: "test-nonce",
|
|
102
|
-
},
|
|
103
|
-
revision: {
|
|
104
|
-
global: 5,
|
|
105
|
-
local: 2,
|
|
106
|
-
custom: 3,
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
state: { data: "test-state" },
|
|
110
|
-
history: {},
|
|
111
|
-
initialState: {},
|
|
112
|
-
operations: {},
|
|
113
|
-
clipboard: [],
|
|
114
|
-
};
|
|
115
|
-
vi.mocked(mockReactorClient.get).mockResolvedValue({
|
|
116
|
-
document: mockDocument,
|
|
117
|
-
childIds: ["child-1", "child-2"],
|
|
48
|
+
const testDoc = createTestDocument();
|
|
49
|
+
await module.client.create(testDoc);
|
|
50
|
+
const result = await resolvers.document(module.client, {
|
|
51
|
+
identifier: testDoc.header.id,
|
|
118
52
|
});
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
expect(result).
|
|
123
|
-
|
|
124
|
-
id: "doc-1",
|
|
125
|
-
name: "Test Document",
|
|
126
|
-
documentType: "powerhouse/document-model",
|
|
127
|
-
slug: "test-doc",
|
|
128
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
129
|
-
lastModifiedAtUtcIso: "2024-01-02T00:00:00Z",
|
|
130
|
-
revisionsList: [
|
|
131
|
-
{ scope: "global", revision: 5 },
|
|
132
|
-
{ scope: "local", revision: 2 },
|
|
133
|
-
{ scope: "custom", revision: 3 },
|
|
134
|
-
],
|
|
135
|
-
state: { data: "test-state" },
|
|
136
|
-
},
|
|
137
|
-
childIds: ["child-1", "child-2"],
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
it("should handle empty revision object", async () => {
|
|
141
|
-
const mockDocument = {
|
|
142
|
-
header: {
|
|
143
|
-
id: "doc-1",
|
|
144
|
-
name: "Test Document",
|
|
145
|
-
documentType: "powerhouse/document-model",
|
|
146
|
-
slug: "test-doc",
|
|
147
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
148
|
-
lastModifiedAtUtcIso: "2024-01-02T00:00:00Z",
|
|
149
|
-
branch: "main",
|
|
150
|
-
sig: {
|
|
151
|
-
publicKey: {},
|
|
152
|
-
nonce: "test-nonce",
|
|
153
|
-
},
|
|
154
|
-
revision: {},
|
|
155
|
-
},
|
|
156
|
-
state: {},
|
|
157
|
-
history: {},
|
|
158
|
-
initialState: {},
|
|
159
|
-
operations: {},
|
|
160
|
-
clipboard: [],
|
|
161
|
-
};
|
|
162
|
-
vi.mocked(mockReactorClient.get).mockResolvedValue({
|
|
163
|
-
document: mockDocument,
|
|
164
|
-
childIds: [],
|
|
165
|
-
});
|
|
166
|
-
const result = await resolvers.document(mockReactorClient, {
|
|
167
|
-
identifier: "doc-1",
|
|
168
|
-
});
|
|
169
|
-
expect(result.document.revisionsList).toEqual([]);
|
|
53
|
+
expect(result.document).toBeDefined();
|
|
54
|
+
expect(result.document.id).toBe(testDoc.header.id);
|
|
55
|
+
expect(result.document.documentType).toBe("powerhouse/document-model");
|
|
56
|
+
expect(result.document.revisionsList).toBeDefined();
|
|
57
|
+
expect(Array.isArray(result.document.revisionsList)).toBe(true);
|
|
170
58
|
});
|
|
171
59
|
});
|
|
172
60
|
describe("documentChildren", () => {
|
|
173
61
|
it("should transform children documents to GraphQL format", async () => {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
lastModifiedAtUtcIso: "2024-01-01T00:00:00Z",
|
|
184
|
-
branch: "main",
|
|
185
|
-
sig: {
|
|
186
|
-
publicKey: {},
|
|
187
|
-
nonce: "test-nonce",
|
|
188
|
-
},
|
|
189
|
-
revision: { global: 1 },
|
|
190
|
-
},
|
|
191
|
-
state: { childData: "test" },
|
|
192
|
-
history: {},
|
|
193
|
-
initialState: {},
|
|
194
|
-
operations: {},
|
|
195
|
-
clipboard: [],
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
header: {
|
|
199
|
-
id: "child-2",
|
|
200
|
-
name: "Child 2",
|
|
201
|
-
documentType: "type-2",
|
|
202
|
-
slug: "child-2",
|
|
203
|
-
createdAtUtcIso: "2024-01-02T00:00:00Z",
|
|
204
|
-
lastModifiedAtUtcIso: "2024-01-02T00:00:00Z",
|
|
205
|
-
branch: "main",
|
|
206
|
-
sig: {
|
|
207
|
-
publicKey: {},
|
|
208
|
-
nonce: "test-nonce",
|
|
209
|
-
},
|
|
210
|
-
revision: { global: 2, local: 1 },
|
|
211
|
-
},
|
|
212
|
-
state: { childData: "test2" },
|
|
213
|
-
history: {},
|
|
214
|
-
initialState: {},
|
|
215
|
-
operations: {},
|
|
216
|
-
clipboard: [],
|
|
217
|
-
},
|
|
218
|
-
],
|
|
219
|
-
options: {
|
|
220
|
-
cursor: "child-cursor",
|
|
221
|
-
limit: 10,
|
|
222
|
-
},
|
|
223
|
-
};
|
|
224
|
-
vi.mocked(mockReactorClient.getChildren).mockResolvedValue(mockChildren);
|
|
225
|
-
const result = await resolvers.documentChildren(mockReactorClient, {
|
|
226
|
-
parentIdentifier: "parent-1",
|
|
227
|
-
});
|
|
228
|
-
expect(result).toEqual({
|
|
229
|
-
cursor: "child-cursor",
|
|
230
|
-
hasNextPage: false,
|
|
231
|
-
hasPreviousPage: false,
|
|
232
|
-
items: [
|
|
233
|
-
{
|
|
234
|
-
id: "child-1",
|
|
235
|
-
name: "Child 1",
|
|
236
|
-
documentType: "type-1",
|
|
237
|
-
slug: "child-1",
|
|
238
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
239
|
-
lastModifiedAtUtcIso: "2024-01-01T00:00:00Z",
|
|
240
|
-
revisionsList: [{ scope: "global", revision: 1 }],
|
|
241
|
-
state: { childData: "test" },
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
id: "child-2",
|
|
245
|
-
name: "Child 2",
|
|
246
|
-
documentType: "type-2",
|
|
247
|
-
slug: "child-2",
|
|
248
|
-
createdAtUtcIso: "2024-01-02T00:00:00Z",
|
|
249
|
-
lastModifiedAtUtcIso: "2024-01-02T00:00:00Z",
|
|
250
|
-
revisionsList: [
|
|
251
|
-
{ scope: "global", revision: 2 },
|
|
252
|
-
{ scope: "local", revision: 1 },
|
|
253
|
-
],
|
|
254
|
-
state: { childData: "test2" },
|
|
255
|
-
},
|
|
256
|
-
],
|
|
257
|
-
totalCount: 2,
|
|
258
|
-
});
|
|
259
|
-
});
|
|
260
|
-
it("should handle empty cursor as null", async () => {
|
|
261
|
-
const mockChildren = {
|
|
262
|
-
results: [],
|
|
263
|
-
options: {
|
|
264
|
-
cursor: "",
|
|
265
|
-
limit: 5,
|
|
266
|
-
},
|
|
267
|
-
};
|
|
268
|
-
vi.mocked(mockReactorClient.getChildren).mockResolvedValue(mockChildren);
|
|
269
|
-
const result = await resolvers.documentChildren(mockReactorClient, {
|
|
270
|
-
parentIdentifier: "parent-1",
|
|
62
|
+
const parent = createTestDocument();
|
|
63
|
+
const child = createTestDocument();
|
|
64
|
+
await module.client.create(parent);
|
|
65
|
+
await module.client.create(child);
|
|
66
|
+
await module.client.addChildren(parent.header.id, [child.header.id]);
|
|
67
|
+
const result = await resolvers.documentChildren(module.client, {
|
|
68
|
+
parentIdentifier: parent.header.id,
|
|
69
|
+
paging: null,
|
|
70
|
+
view: null,
|
|
271
71
|
});
|
|
272
|
-
expect(result.
|
|
72
|
+
expect(result.items.length).toBe(1);
|
|
73
|
+
expect(result.items[0].id).toBe(child.header.id);
|
|
273
74
|
});
|
|
274
75
|
});
|
|
275
76
|
describe("documentParents", () => {
|
|
276
77
|
it("should transform parent documents to GraphQL format", async () => {
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
lastModifiedAtUtcIso: "2024-01-01T00:00:00Z",
|
|
287
|
-
branch: "main",
|
|
288
|
-
sig: {
|
|
289
|
-
publicKey: {},
|
|
290
|
-
nonce: "test-nonce",
|
|
291
|
-
},
|
|
292
|
-
revision: { global: 10, local: 5, branch: 2 },
|
|
293
|
-
},
|
|
294
|
-
state: { parentData: "test" },
|
|
295
|
-
history: {},
|
|
296
|
-
initialState: {},
|
|
297
|
-
operations: {},
|
|
298
|
-
clipboard: [],
|
|
299
|
-
},
|
|
300
|
-
],
|
|
301
|
-
options: {
|
|
302
|
-
cursor: "parent-cursor",
|
|
303
|
-
limit: 10,
|
|
304
|
-
},
|
|
305
|
-
};
|
|
306
|
-
vi.mocked(mockReactorClient.getParents).mockResolvedValue(mockParents);
|
|
307
|
-
const result = await resolvers.documentParents(mockReactorClient, {
|
|
308
|
-
childIdentifier: "child-1",
|
|
309
|
-
});
|
|
310
|
-
expect(result).toEqual({
|
|
311
|
-
cursor: "parent-cursor",
|
|
312
|
-
hasNextPage: false,
|
|
313
|
-
hasPreviousPage: false,
|
|
314
|
-
items: [
|
|
315
|
-
{
|
|
316
|
-
id: "parent-1",
|
|
317
|
-
name: "Parent 1",
|
|
318
|
-
documentType: "folder",
|
|
319
|
-
slug: "parent-1",
|
|
320
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
321
|
-
lastModifiedAtUtcIso: "2024-01-01T00:00:00Z",
|
|
322
|
-
revisionsList: [
|
|
323
|
-
{ scope: "global", revision: 10 },
|
|
324
|
-
{ scope: "local", revision: 5 },
|
|
325
|
-
{ scope: "branch", revision: 2 },
|
|
326
|
-
],
|
|
327
|
-
state: { parentData: "test" },
|
|
328
|
-
},
|
|
329
|
-
],
|
|
330
|
-
totalCount: 1,
|
|
78
|
+
const parent = createTestDocument();
|
|
79
|
+
const child = createTestDocument();
|
|
80
|
+
await module.client.create(parent);
|
|
81
|
+
await module.client.create(child);
|
|
82
|
+
await module.client.addChildren(parent.header.id, [child.header.id]);
|
|
83
|
+
const result = await resolvers.documentParents(module.client, {
|
|
84
|
+
childIdentifier: child.header.id,
|
|
85
|
+
paging: null,
|
|
86
|
+
view: null,
|
|
331
87
|
});
|
|
88
|
+
expect(result.items.length).toBe(1);
|
|
89
|
+
expect(result.items[0].id).toBe(parent.header.id);
|
|
332
90
|
});
|
|
333
91
|
});
|
|
334
92
|
describe("findDocuments", () => {
|
|
335
|
-
it("should
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
header: {
|
|
340
|
-
id: "doc-1",
|
|
341
|
-
name: "Document 1",
|
|
342
|
-
documentType: "powerhouse/document-model",
|
|
343
|
-
slug: "doc-1",
|
|
344
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
345
|
-
lastModifiedAtUtcIso: "2024-01-01T00:00:00Z",
|
|
346
|
-
branch: "main",
|
|
347
|
-
sig: {
|
|
348
|
-
publicKey: {},
|
|
349
|
-
nonce: "test-nonce",
|
|
350
|
-
},
|
|
351
|
-
revision: { global: 1 },
|
|
352
|
-
},
|
|
353
|
-
state: { doc1Data: "test" },
|
|
354
|
-
history: {},
|
|
355
|
-
initialState: {},
|
|
356
|
-
operations: {},
|
|
357
|
-
clipboard: [],
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
header: {
|
|
361
|
-
id: "doc-2",
|
|
362
|
-
name: "Document 2",
|
|
363
|
-
documentType: "powerhouse/document-model",
|
|
364
|
-
slug: "doc-2",
|
|
365
|
-
createdAtUtcIso: "2024-01-02T00:00:00Z",
|
|
366
|
-
lastModifiedAtUtcIso: "2024-01-02T00:00:00Z",
|
|
367
|
-
branch: "main",
|
|
368
|
-
sig: {
|
|
369
|
-
publicKey: {},
|
|
370
|
-
nonce: "test-nonce",
|
|
371
|
-
},
|
|
372
|
-
revision: { global: 2 },
|
|
373
|
-
},
|
|
374
|
-
state: { doc2Data: "test" },
|
|
375
|
-
history: {},
|
|
376
|
-
initialState: {},
|
|
377
|
-
operations: {},
|
|
378
|
-
clipboard: [],
|
|
379
|
-
},
|
|
380
|
-
],
|
|
381
|
-
options: {
|
|
382
|
-
cursor: "search-cursor",
|
|
383
|
-
limit: 10,
|
|
384
|
-
},
|
|
385
|
-
};
|
|
386
|
-
vi.mocked(mockReactorClient.find).mockResolvedValue(mockDocuments);
|
|
387
|
-
const result = await resolvers.findDocuments(mockReactorClient, {
|
|
93
|
+
it("should find documents by type", async () => {
|
|
94
|
+
const testDoc = createTestDocument();
|
|
95
|
+
await module.client.create(testDoc);
|
|
96
|
+
const result = await resolvers.findDocuments(module.client, {
|
|
388
97
|
search: {
|
|
389
98
|
type: "powerhouse/document-model",
|
|
390
|
-
parentId:
|
|
391
|
-
},
|
|
392
|
-
});
|
|
393
|
-
expect(result).toEqual({
|
|
394
|
-
cursor: "search-cursor",
|
|
395
|
-
hasNextPage: false,
|
|
396
|
-
hasPreviousPage: false,
|
|
397
|
-
items: [
|
|
398
|
-
{
|
|
399
|
-
id: "doc-1",
|
|
400
|
-
name: "Document 1",
|
|
401
|
-
documentType: "powerhouse/document-model",
|
|
402
|
-
slug: "doc-1",
|
|
403
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
404
|
-
lastModifiedAtUtcIso: "2024-01-01T00:00:00Z",
|
|
405
|
-
revisionsList: [{ scope: "global", revision: 1 }],
|
|
406
|
-
state: { doc1Data: "test" },
|
|
407
|
-
},
|
|
408
|
-
{
|
|
409
|
-
id: "doc-2",
|
|
410
|
-
name: "Document 2",
|
|
411
|
-
documentType: "powerhouse/document-model",
|
|
412
|
-
slug: "doc-2",
|
|
413
|
-
createdAtUtcIso: "2024-01-02T00:00:00Z",
|
|
414
|
-
lastModifiedAtUtcIso: "2024-01-02T00:00:00Z",
|
|
415
|
-
revisionsList: [{ scope: "global", revision: 2 }],
|
|
416
|
-
state: { doc2Data: "test" },
|
|
417
|
-
},
|
|
418
|
-
],
|
|
419
|
-
totalCount: 2,
|
|
420
|
-
});
|
|
421
|
-
});
|
|
422
|
-
});
|
|
423
|
-
describe("jobStatus", () => {
|
|
424
|
-
it("should transform completed job with all fields", async () => {
|
|
425
|
-
const mockJobInfo = {
|
|
426
|
-
id: "job-123",
|
|
427
|
-
status: JobStatus.READ_MODELS_READY,
|
|
428
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
429
|
-
completedAtUtcIso: "2024-01-01T00:05:00Z",
|
|
430
|
-
result: { success: true, data: "test" },
|
|
431
|
-
consistencyToken: {
|
|
432
|
-
version: 1,
|
|
433
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
434
|
-
coordinates: [],
|
|
435
|
-
},
|
|
436
|
-
};
|
|
437
|
-
vi.mocked(mockReactorClient.getJobStatus).mockResolvedValue(mockJobInfo);
|
|
438
|
-
const result = await resolvers.jobStatus(mockReactorClient, {
|
|
439
|
-
jobId: "job-123",
|
|
440
|
-
});
|
|
441
|
-
expect(result).toEqual({
|
|
442
|
-
id: "job-123",
|
|
443
|
-
status: JobStatus.READ_MODELS_READY,
|
|
444
|
-
createdAt: "2024-01-01T00:00:00Z",
|
|
445
|
-
completedAt: "2024-01-01T00:05:00Z",
|
|
446
|
-
error: null,
|
|
447
|
-
result: { success: true, data: "test" },
|
|
448
|
-
});
|
|
449
|
-
});
|
|
450
|
-
it("should transform failed job with error", async () => {
|
|
451
|
-
const mockJobInfo = {
|
|
452
|
-
id: "job-456",
|
|
453
|
-
status: JobStatus.FAILED,
|
|
454
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
455
|
-
error: { message: "Job failed due to timeout", stack: "stack trace" },
|
|
456
|
-
consistencyToken: {
|
|
457
|
-
version: 1,
|
|
458
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
459
|
-
coordinates: [],
|
|
460
|
-
},
|
|
461
|
-
};
|
|
462
|
-
vi.mocked(mockReactorClient.getJobStatus).mockResolvedValue(mockJobInfo);
|
|
463
|
-
const result = await resolvers.jobStatus(mockReactorClient, {
|
|
464
|
-
jobId: "job-456",
|
|
465
|
-
});
|
|
466
|
-
expect(result).toEqual({
|
|
467
|
-
id: "job-456",
|
|
468
|
-
status: JobStatus.FAILED,
|
|
469
|
-
createdAt: "2024-01-01T00:00:00Z",
|
|
470
|
-
completedAt: null,
|
|
471
|
-
error: "Job failed due to timeout",
|
|
472
|
-
result: null,
|
|
473
|
-
});
|
|
474
|
-
});
|
|
475
|
-
it("should transform pending job with minimal fields", async () => {
|
|
476
|
-
const mockJobInfo = {
|
|
477
|
-
id: "job-789",
|
|
478
|
-
status: JobStatus.PENDING,
|
|
479
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
480
|
-
consistencyToken: {
|
|
481
|
-
version: 1,
|
|
482
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
483
|
-
coordinates: [],
|
|
99
|
+
parentId: null,
|
|
484
100
|
},
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
const result = await resolvers.jobStatus(mockReactorClient, {
|
|
488
|
-
jobId: "job-789",
|
|
489
|
-
});
|
|
490
|
-
expect(result).toEqual({
|
|
491
|
-
id: "job-789",
|
|
492
|
-
status: JobStatus.PENDING,
|
|
493
|
-
createdAt: "2024-01-01T00:00:00Z",
|
|
494
|
-
completedAt: null,
|
|
495
|
-
error: null,
|
|
496
|
-
result: null,
|
|
497
|
-
});
|
|
498
|
-
});
|
|
499
|
-
it("should handle undefined optional fields as null", async () => {
|
|
500
|
-
const mockJobInfo = {
|
|
501
|
-
id: "job-999",
|
|
502
|
-
status: JobStatus.RUNNING,
|
|
503
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
504
|
-
completedAtUtcIso: undefined,
|
|
505
|
-
error: undefined,
|
|
506
|
-
result: undefined,
|
|
507
|
-
consistencyToken: {
|
|
508
|
-
version: 1,
|
|
509
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
510
|
-
coordinates: [],
|
|
511
|
-
},
|
|
512
|
-
};
|
|
513
|
-
vi.mocked(mockReactorClient.getJobStatus).mockResolvedValue(mockJobInfo);
|
|
514
|
-
const result = await resolvers.jobStatus(mockReactorClient, {
|
|
515
|
-
jobId: "job-999",
|
|
101
|
+
paging: null,
|
|
102
|
+
view: null,
|
|
516
103
|
});
|
|
517
|
-
expect(result.
|
|
518
|
-
expect(result.
|
|
519
|
-
expect(result.result).toBeNull();
|
|
104
|
+
expect(result.items.length).toBeGreaterThan(0);
|
|
105
|
+
expect(result.items[0].documentType).toBe("powerhouse/document-model");
|
|
520
106
|
});
|
|
521
107
|
});
|
|
522
|
-
describe("Error
|
|
523
|
-
it("should
|
|
524
|
-
|
|
525
|
-
await expect(resolvers.documentModels(mockReactorClient, {})).rejects.toThrow("Failed to fetch document models: Network timeout");
|
|
526
|
-
});
|
|
527
|
-
it("should handle unknown error types", async () => {
|
|
528
|
-
vi.mocked(mockReactorClient.get).mockRejectedValue("String error");
|
|
529
|
-
await expect(resolvers.document(mockReactorClient, { identifier: "doc-1" })).rejects.toThrow("Failed to fetch document: Unknown error");
|
|
530
|
-
});
|
|
531
|
-
it("should handle conversion errors separately from fetch errors", async () => {
|
|
532
|
-
const invalidDocument = {
|
|
533
|
-
header: null, // Invalid structure
|
|
534
|
-
};
|
|
535
|
-
vi.mocked(mockReactorClient.get).mockResolvedValue({
|
|
536
|
-
document: invalidDocument,
|
|
537
|
-
childIds: [],
|
|
538
|
-
});
|
|
539
|
-
await expect(resolvers.document(mockReactorClient, { identifier: "doc-1" })).rejects.toThrow("Failed to convert document to GraphQL");
|
|
108
|
+
describe("Error Handling", () => {
|
|
109
|
+
it("should throw error for non-existent document", async () => {
|
|
110
|
+
await expect(resolvers.document(module.client, { identifier: "non-existent-id" })).rejects.toThrow();
|
|
540
111
|
});
|
|
541
112
|
});
|
|
542
113
|
});
|
|
543
114
|
describe("ReactorSubgraph Mutation Resolvers", () => {
|
|
544
|
-
let
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
publicKey: {},
|
|
556
|
-
nonce: "test-nonce",
|
|
557
|
-
},
|
|
558
|
-
revision: { global: 1 },
|
|
559
|
-
},
|
|
560
|
-
state: { data: "test" },
|
|
561
|
-
history: {},
|
|
562
|
-
initialState: {},
|
|
563
|
-
operations: {},
|
|
564
|
-
clipboard: [],
|
|
565
|
-
...overrides,
|
|
115
|
+
let module;
|
|
116
|
+
beforeEach(async () => {
|
|
117
|
+
const reactorBuilder = new ReactorBuilder()
|
|
118
|
+
.withDocumentModels([
|
|
119
|
+
driveDocumentModelModule,
|
|
120
|
+
documentModelDocumentModelModule,
|
|
121
|
+
])
|
|
122
|
+
.withFeatures({ legacyStorageEnabled: false });
|
|
123
|
+
module = await new ReactorClientBuilder()
|
|
124
|
+
.withReactorBuilder(reactorBuilder)
|
|
125
|
+
.buildModule();
|
|
566
126
|
});
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
mockReactorClient = {
|
|
570
|
-
getDocumentModels: vi.fn(),
|
|
571
|
-
get: vi.fn(),
|
|
572
|
-
getChildren: vi.fn(),
|
|
573
|
-
getParents: vi.fn(),
|
|
574
|
-
find: vi.fn(),
|
|
575
|
-
getJobStatus: vi.fn(),
|
|
576
|
-
waitForJob: vi.fn(),
|
|
577
|
-
create: vi.fn(),
|
|
578
|
-
createEmpty: vi.fn(),
|
|
579
|
-
execute: vi.fn(),
|
|
580
|
-
executeAsync: vi.fn(),
|
|
581
|
-
rename: vi.fn(),
|
|
582
|
-
addChildren: vi.fn(),
|
|
583
|
-
removeChildren: vi.fn(),
|
|
584
|
-
moveChildren: vi.fn(),
|
|
585
|
-
deleteDocument: vi.fn(),
|
|
586
|
-
deleteDocuments: vi.fn(),
|
|
587
|
-
subscribe: vi.fn(),
|
|
588
|
-
};
|
|
127
|
+
afterEach(() => {
|
|
128
|
+
module.reactor.kill();
|
|
589
129
|
});
|
|
590
130
|
describe("createDocument", () => {
|
|
591
131
|
it("should create a document and transform to GraphQL format", async () => {
|
|
592
|
-
const inputDocument =
|
|
593
|
-
const
|
|
594
|
-
header: {
|
|
595
|
-
...inputDocument.header,
|
|
596
|
-
id: "new-doc-id",
|
|
597
|
-
},
|
|
598
|
-
});
|
|
599
|
-
vi.mocked(mockReactorClient.create).mockResolvedValue(createdDocument);
|
|
600
|
-
const result = await resolvers.createDocument(mockReactorClient, {
|
|
601
|
-
document: inputDocument,
|
|
602
|
-
parentIdentifier: "parent-1",
|
|
603
|
-
});
|
|
604
|
-
expect(mockReactorClient.create).toHaveBeenCalledWith(inputDocument, "parent-1");
|
|
605
|
-
expect(result.id).toBe("new-doc-id");
|
|
606
|
-
expect(result.name).toBe("Test Document");
|
|
607
|
-
expect(result.documentType).toBe("powerhouse/document-model");
|
|
608
|
-
});
|
|
609
|
-
it("should handle null parentIdentifier", async () => {
|
|
610
|
-
const inputDocument = createMockDocument();
|
|
611
|
-
vi.mocked(mockReactorClient.create).mockResolvedValue(inputDocument);
|
|
612
|
-
await resolvers.createDocument(mockReactorClient, {
|
|
132
|
+
const inputDocument = createTestDocument();
|
|
133
|
+
const result = await resolvers.createDocument(module.client, {
|
|
613
134
|
document: inputDocument,
|
|
614
135
|
parentIdentifier: null,
|
|
615
136
|
});
|
|
616
|
-
expect(
|
|
137
|
+
expect(result.id).toBe(inputDocument.header.id);
|
|
138
|
+
expect(result.documentType).toBe("powerhouse/document-model");
|
|
617
139
|
});
|
|
618
140
|
it("should reject invalid document input", async () => {
|
|
619
|
-
await expect(resolvers.createDocument(
|
|
141
|
+
await expect(resolvers.createDocument(module.client, {
|
|
620
142
|
document: null,
|
|
621
143
|
parentIdentifier: null,
|
|
622
144
|
})).rejects.toThrow("Invalid document: must be an object");
|
|
623
145
|
});
|
|
624
146
|
it("should reject document without header", async () => {
|
|
625
|
-
await expect(resolvers.createDocument(
|
|
147
|
+
await expect(resolvers.createDocument(module.client, {
|
|
626
148
|
document: { state: {} },
|
|
627
149
|
parentIdentifier: null,
|
|
628
150
|
})).rejects.toThrow("Invalid document: missing or invalid header");
|
|
629
151
|
});
|
|
630
|
-
it("should handle creation errors", async () => {
|
|
631
|
-
const inputDocument = createMockDocument();
|
|
632
|
-
vi.mocked(mockReactorClient.create).mockRejectedValue(new Error("Database error"));
|
|
633
|
-
await expect(resolvers.createDocument(mockReactorClient, {
|
|
634
|
-
document: inputDocument,
|
|
635
|
-
parentIdentifier: null,
|
|
636
|
-
})).rejects.toThrow("Failed to create document: Database error");
|
|
637
|
-
});
|
|
638
152
|
});
|
|
639
153
|
describe("createEmptyDocument", () => {
|
|
640
154
|
it("should create an empty document of specified type", async () => {
|
|
641
|
-
const
|
|
642
|
-
vi.mocked(mockReactorClient.createEmpty).mockResolvedValue(emptyDocument);
|
|
643
|
-
const result = await resolvers.createEmptyDocument(mockReactorClient, {
|
|
644
|
-
documentType: "powerhouse/document-model",
|
|
645
|
-
parentIdentifier: "parent-1",
|
|
646
|
-
});
|
|
647
|
-
expect(mockReactorClient.createEmpty).toHaveBeenCalledWith("powerhouse/document-model", "parent-1");
|
|
648
|
-
expect(result.id).toBe("doc-1");
|
|
649
|
-
expect(result.documentType).toBe("powerhouse/document-model");
|
|
650
|
-
});
|
|
651
|
-
it("should handle null parentIdentifier", async () => {
|
|
652
|
-
const emptyDocument = createMockDocument();
|
|
653
|
-
vi.mocked(mockReactorClient.createEmpty).mockResolvedValue(emptyDocument);
|
|
654
|
-
await resolvers.createEmptyDocument(mockReactorClient, {
|
|
155
|
+
const result = await resolvers.createEmptyDocument(module.client, {
|
|
655
156
|
documentType: "powerhouse/document-model",
|
|
656
157
|
parentIdentifier: null,
|
|
657
158
|
});
|
|
658
|
-
expect(
|
|
659
|
-
|
|
660
|
-
it("should handle creation errors", async () => {
|
|
661
|
-
vi.mocked(mockReactorClient.createEmpty).mockRejectedValue(new Error("Invalid document type"));
|
|
662
|
-
await expect(resolvers.createEmptyDocument(mockReactorClient, {
|
|
663
|
-
documentType: "invalid/type",
|
|
664
|
-
parentIdentifier: null,
|
|
665
|
-
})).rejects.toThrow("Failed to create empty document: Invalid document type");
|
|
159
|
+
expect(result.id).toBeDefined();
|
|
160
|
+
expect(result.documentType).toBe("powerhouse/document-model");
|
|
666
161
|
});
|
|
667
162
|
});
|
|
668
163
|
describe("renameDocument", () => {
|
|
669
164
|
it("should rename a document", async () => {
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
},
|
|
675
|
-
});
|
|
676
|
-
vi.mocked(mockReactorClient.rename).mockResolvedValue(renamedDocument);
|
|
677
|
-
const result = await resolvers.renameDocument(mockReactorClient, {
|
|
678
|
-
documentIdentifier: "doc-1",
|
|
679
|
-
name: "New Name",
|
|
680
|
-
branch: "main",
|
|
681
|
-
});
|
|
682
|
-
expect(mockReactorClient.rename).toHaveBeenCalledWith("doc-1", "New Name", "main");
|
|
683
|
-
expect(result.name).toBe("New Name");
|
|
684
|
-
});
|
|
685
|
-
it("should handle null view filter", async () => {
|
|
686
|
-
const renamedDocument = createMockDocument();
|
|
687
|
-
vi.mocked(mockReactorClient.rename).mockResolvedValue(renamedDocument);
|
|
688
|
-
await resolvers.renameDocument(mockReactorClient, {
|
|
689
|
-
documentIdentifier: "doc-1",
|
|
165
|
+
const testDoc = createTestDocument();
|
|
166
|
+
await module.client.create(testDoc);
|
|
167
|
+
const result = await resolvers.renameDocument(module.client, {
|
|
168
|
+
documentIdentifier: testDoc.header.id,
|
|
690
169
|
name: "New Name",
|
|
691
170
|
branch: null,
|
|
692
171
|
});
|
|
693
|
-
expect(
|
|
694
|
-
});
|
|
695
|
-
it("should handle rename errors", async () => {
|
|
696
|
-
vi.mocked(mockReactorClient.rename).mockRejectedValue(new Error("Document not found"));
|
|
697
|
-
await expect(resolvers.renameDocument(mockReactorClient, {
|
|
698
|
-
documentIdentifier: "doc-1",
|
|
699
|
-
name: "New Name",
|
|
700
|
-
branch: null,
|
|
701
|
-
})).rejects.toThrow("Failed to rename document: Document not found");
|
|
172
|
+
expect(result.name).toBe("New Name");
|
|
702
173
|
});
|
|
703
174
|
});
|
|
704
175
|
describe("addChildren", () => {
|
|
705
176
|
it("should add children to a parent document", async () => {
|
|
706
|
-
const
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
expect(mockReactorClient.addChildren).toHaveBeenCalledWith("parent-1", ["child-1", "child-2"], "main");
|
|
714
|
-
expect(result.id).toBe("doc-1");
|
|
715
|
-
});
|
|
716
|
-
it("should handle errors when adding children", async () => {
|
|
717
|
-
vi.mocked(mockReactorClient.addChildren).mockRejectedValue(new Error("Child not found"));
|
|
718
|
-
await expect(resolvers.addChildren(mockReactorClient, {
|
|
719
|
-
parentIdentifier: "parent-1",
|
|
720
|
-
documentIdentifiers: ["child-1"],
|
|
177
|
+
const parent = createTestDocument();
|
|
178
|
+
const child = createTestDocument();
|
|
179
|
+
await module.client.create(parent);
|
|
180
|
+
await module.client.create(child);
|
|
181
|
+
const result = await resolvers.addChildren(module.client, {
|
|
182
|
+
parentIdentifier: parent.header.id,
|
|
183
|
+
documentIdentifiers: [child.header.id],
|
|
721
184
|
branch: null,
|
|
722
|
-
})
|
|
185
|
+
});
|
|
186
|
+
expect(result.id).toBe(parent.header.id);
|
|
723
187
|
});
|
|
724
188
|
});
|
|
725
189
|
describe("removeChildren", () => {
|
|
726
190
|
it("should remove children from a parent document", async () => {
|
|
727
|
-
const
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
191
|
+
const parent = createTestDocument();
|
|
192
|
+
const child = createTestDocument();
|
|
193
|
+
await module.client.create(parent);
|
|
194
|
+
await module.client.create(child);
|
|
195
|
+
await module.client.addChildren(parent.header.id, [child.header.id]);
|
|
196
|
+
const result = await resolvers.removeChildren(module.client, {
|
|
197
|
+
parentIdentifier: parent.header.id,
|
|
198
|
+
documentIdentifiers: [child.header.id],
|
|
732
199
|
branch: null,
|
|
733
200
|
});
|
|
734
|
-
expect(
|
|
735
|
-
expect(result.id).toBe("doc-1");
|
|
736
|
-
});
|
|
737
|
-
it("should handle errors when removing children", async () => {
|
|
738
|
-
vi.mocked(mockReactorClient.removeChildren).mockRejectedValue(new Error("Child relationship not found"));
|
|
739
|
-
await expect(resolvers.removeChildren(mockReactorClient, {
|
|
740
|
-
parentIdentifier: "parent-1",
|
|
741
|
-
documentIdentifiers: ["child-1"],
|
|
742
|
-
branch: null,
|
|
743
|
-
})).rejects.toThrow("Failed to remove children: Child relationship not found");
|
|
744
|
-
});
|
|
745
|
-
});
|
|
746
|
-
describe("moveChildren", () => {
|
|
747
|
-
it("should move children between parent documents", async () => {
|
|
748
|
-
const sourceDocument = createMockDocument();
|
|
749
|
-
const targetDocument = createMockDocument();
|
|
750
|
-
// Update IDs after creation
|
|
751
|
-
sourceDocument.header.id = "source-1";
|
|
752
|
-
targetDocument.header.id = "target-1";
|
|
753
|
-
vi.mocked(mockReactorClient.moveChildren).mockResolvedValue({
|
|
754
|
-
source: sourceDocument,
|
|
755
|
-
target: targetDocument,
|
|
756
|
-
});
|
|
757
|
-
const result = await resolvers.moveChildren(mockReactorClient, {
|
|
758
|
-
sourceParentIdentifier: "source-1",
|
|
759
|
-
targetParentIdentifier: "target-1",
|
|
760
|
-
documentIdentifiers: ["child-1", "child-2"],
|
|
761
|
-
branch: "main",
|
|
762
|
-
});
|
|
763
|
-
expect(mockReactorClient.moveChildren).toHaveBeenCalledWith("source-1", "target-1", ["child-1", "child-2"], "main");
|
|
764
|
-
expect(result.source.id).toBe("source-1");
|
|
765
|
-
expect(result.target.id).toBe("target-1");
|
|
766
|
-
});
|
|
767
|
-
it("should handle errors when moving children", async () => {
|
|
768
|
-
vi.mocked(mockReactorClient.moveChildren).mockRejectedValue(new Error("Target parent not found"));
|
|
769
|
-
await expect(resolvers.moveChildren(mockReactorClient, {
|
|
770
|
-
sourceParentIdentifier: "source-1",
|
|
771
|
-
targetParentIdentifier: "target-1",
|
|
772
|
-
documentIdentifiers: ["child-1"],
|
|
773
|
-
branch: null,
|
|
774
|
-
})).rejects.toThrow("Failed to move children: Target parent not found");
|
|
201
|
+
expect(result.id).toBe(parent.header.id);
|
|
775
202
|
});
|
|
776
203
|
});
|
|
777
204
|
describe("deleteDocument", () => {
|
|
778
|
-
it("should delete a document
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
205
|
+
it("should delete a document", async () => {
|
|
206
|
+
const testDoc = createTestDocument();
|
|
207
|
+
await module.client.create(testDoc);
|
|
208
|
+
const result = await resolvers.deleteDocument(module.client, {
|
|
209
|
+
identifier: testDoc.header.id,
|
|
782
210
|
propagate: null,
|
|
783
211
|
});
|
|
784
|
-
expect(mockReactorClient.deleteDocument).toHaveBeenCalledWith("doc-1", undefined);
|
|
785
|
-
expect(result).toBe(true);
|
|
786
|
-
});
|
|
787
|
-
it("should delete a document with CASCADE propagation", async () => {
|
|
788
|
-
vi.mocked(mockReactorClient.deleteDocument).mockResolvedValue();
|
|
789
|
-
const result = await resolvers.deleteDocument(mockReactorClient, {
|
|
790
|
-
identifier: "doc-1",
|
|
791
|
-
propagate: "CASCADE",
|
|
792
|
-
});
|
|
793
|
-
expect(mockReactorClient.deleteDocument).toHaveBeenCalledWith("doc-1", "CASCADE");
|
|
794
212
|
expect(result).toBe(true);
|
|
795
213
|
});
|
|
796
|
-
it("should handle deletion errors", async () => {
|
|
797
|
-
vi.mocked(mockReactorClient.deleteDocument).mockRejectedValue(new Error("Document not found"));
|
|
798
|
-
await expect(resolvers.deleteDocument(mockReactorClient, {
|
|
799
|
-
identifier: "doc-1",
|
|
800
|
-
propagate: null,
|
|
801
|
-
})).rejects.toThrow("Failed to delete document: Document not found");
|
|
802
|
-
});
|
|
803
214
|
});
|
|
804
215
|
describe("deleteDocuments", () => {
|
|
805
216
|
it("should delete multiple documents", async () => {
|
|
806
|
-
|
|
807
|
-
const
|
|
808
|
-
|
|
809
|
-
|
|
217
|
+
const doc1 = createTestDocument();
|
|
218
|
+
const doc2 = createTestDocument();
|
|
219
|
+
await module.client.create(doc1);
|
|
220
|
+
await module.client.create(doc2);
|
|
221
|
+
const result = await resolvers.deleteDocuments(module.client, {
|
|
222
|
+
identifiers: [doc1.header.id, doc2.header.id],
|
|
223
|
+
propagate: null,
|
|
810
224
|
});
|
|
811
|
-
expect(mockReactorClient.deleteDocuments).toHaveBeenCalledWith(["doc-1", "doc-2", "doc-3"], "ORPHAN");
|
|
812
225
|
expect(result).toBe(true);
|
|
813
226
|
});
|
|
814
|
-
it("should handle batch deletion errors", async () => {
|
|
815
|
-
vi.mocked(mockReactorClient.deleteDocuments).mockRejectedValue(new Error("Partial deletion failed"));
|
|
816
|
-
await expect(resolvers.deleteDocuments(mockReactorClient, {
|
|
817
|
-
identifiers: ["doc-1", "doc-2"],
|
|
818
|
-
propagate: null,
|
|
819
|
-
})).rejects.toThrow("Failed to delete documents: Partial deletion failed");
|
|
820
|
-
});
|
|
821
227
|
});
|
|
822
228
|
describe("mutateDocument", () => {
|
|
823
229
|
it("should mutate a document with validated actions", async () => {
|
|
824
|
-
const
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
id: "action-1",
|
|
831
|
-
timestampUtcMs: "2024-01-01T00:00:00Z",
|
|
832
|
-
},
|
|
230
|
+
const testDoc = createTestDocument();
|
|
231
|
+
await module.client.create(testDoc);
|
|
232
|
+
const actions = [
|
|
233
|
+
documentModelDocumentModelModule.actions.setModelName({
|
|
234
|
+
name: "New Model Name",
|
|
235
|
+
}),
|
|
833
236
|
];
|
|
834
|
-
const
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
name: "powerhouse/document-model",
|
|
838
|
-
specifications: [
|
|
839
|
-
{
|
|
840
|
-
modules: [
|
|
841
|
-
{
|
|
842
|
-
operations: [{ name: "SET_NAME", scope: "global" }],
|
|
843
|
-
},
|
|
844
|
-
],
|
|
845
|
-
},
|
|
846
|
-
],
|
|
847
|
-
},
|
|
848
|
-
},
|
|
849
|
-
actions: {
|
|
850
|
-
setName: vi.fn((input) => mockActions[0]),
|
|
851
|
-
},
|
|
852
|
-
};
|
|
853
|
-
vi.mocked(mockReactorClient.get).mockResolvedValue({
|
|
854
|
-
document: mockDocument,
|
|
855
|
-
childIds: [],
|
|
856
|
-
});
|
|
857
|
-
vi.mocked(mockReactorClient.getDocumentModels).mockResolvedValue({
|
|
858
|
-
results: [mockModule],
|
|
859
|
-
options: { cursor: "", limit: 10 },
|
|
860
|
-
});
|
|
861
|
-
vi.mocked(mockReactorClient.execute).mockResolvedValue(mockDocument);
|
|
862
|
-
const result = await resolvers.mutateDocument(mockReactorClient, {
|
|
863
|
-
documentIdentifier: "doc-1",
|
|
864
|
-
actions: mockActions,
|
|
237
|
+
const result = await resolvers.mutateDocument(module.client, {
|
|
238
|
+
documentIdentifier: testDoc.header.id,
|
|
239
|
+
actions: actions,
|
|
865
240
|
view: { branch: "main", scopes: null },
|
|
866
241
|
});
|
|
867
|
-
expect(
|
|
868
|
-
expect(result.id).toBe("doc-1");
|
|
869
|
-
});
|
|
870
|
-
it("should use default branch when view is null", async () => {
|
|
871
|
-
const mockDocument = createMockDocument();
|
|
872
|
-
const mockActions = [
|
|
873
|
-
{
|
|
874
|
-
type: "SET_NAME",
|
|
875
|
-
scope: "global",
|
|
876
|
-
input: { name: "New Name" },
|
|
877
|
-
id: "action-1",
|
|
878
|
-
timestampUtcMs: "2024-01-01T00:00:00Z",
|
|
879
|
-
},
|
|
880
|
-
];
|
|
881
|
-
const mockModule = {
|
|
882
|
-
documentModel: {
|
|
883
|
-
global: {
|
|
884
|
-
name: "powerhouse/document-model",
|
|
885
|
-
specifications: [
|
|
886
|
-
{
|
|
887
|
-
modules: [
|
|
888
|
-
{
|
|
889
|
-
operations: [{ name: "SET_NAME", scope: "global" }],
|
|
890
|
-
},
|
|
891
|
-
],
|
|
892
|
-
},
|
|
893
|
-
],
|
|
894
|
-
},
|
|
895
|
-
},
|
|
896
|
-
actions: {
|
|
897
|
-
setName: vi.fn((input) => mockActions[0]),
|
|
898
|
-
},
|
|
899
|
-
};
|
|
900
|
-
vi.mocked(mockReactorClient.get).mockResolvedValue({
|
|
901
|
-
document: mockDocument,
|
|
902
|
-
childIds: [],
|
|
903
|
-
});
|
|
904
|
-
vi.mocked(mockReactorClient.getDocumentModels).mockResolvedValue({
|
|
905
|
-
results: [mockModule],
|
|
906
|
-
options: { cursor: "", limit: 10 },
|
|
907
|
-
});
|
|
908
|
-
vi.mocked(mockReactorClient.execute).mockResolvedValue(mockDocument);
|
|
909
|
-
await resolvers.mutateDocument(mockReactorClient, {
|
|
910
|
-
documentIdentifier: "doc-1",
|
|
911
|
-
actions: mockActions,
|
|
912
|
-
view: null,
|
|
913
|
-
});
|
|
914
|
-
expect(mockReactorClient.execute).toHaveBeenCalledWith("doc-1", "main", mockActions);
|
|
915
|
-
});
|
|
916
|
-
it("should reject invalid action structure", async () => {
|
|
917
|
-
await expect(resolvers.mutateDocument(mockReactorClient, {
|
|
918
|
-
documentIdentifier: "doc-1",
|
|
919
|
-
actions: [{ invalidAction: true }],
|
|
920
|
-
view: null,
|
|
921
|
-
})).rejects.toThrow("Action at index 0");
|
|
922
|
-
});
|
|
923
|
-
it("should handle mutation errors", async () => {
|
|
924
|
-
const mockDocument = createMockDocument();
|
|
925
|
-
const mockActions = [
|
|
926
|
-
{
|
|
927
|
-
type: "SET_NAME",
|
|
928
|
-
scope: "global",
|
|
929
|
-
input: { name: "New Name" },
|
|
930
|
-
id: "action-1",
|
|
931
|
-
timestampUtcMs: "2024-01-01T00:00:00Z",
|
|
932
|
-
},
|
|
933
|
-
];
|
|
934
|
-
const mockModule = {
|
|
935
|
-
documentModel: {
|
|
936
|
-
global: {
|
|
937
|
-
name: "powerhouse/document-model",
|
|
938
|
-
specifications: [
|
|
939
|
-
{
|
|
940
|
-
modules: [
|
|
941
|
-
{
|
|
942
|
-
operations: [{ name: "SET_NAME", scope: "global" }],
|
|
943
|
-
},
|
|
944
|
-
],
|
|
945
|
-
},
|
|
946
|
-
],
|
|
947
|
-
},
|
|
948
|
-
},
|
|
949
|
-
actions: {
|
|
950
|
-
setName: vi.fn((input) => mockActions[0]),
|
|
951
|
-
},
|
|
952
|
-
};
|
|
953
|
-
vi.mocked(mockReactorClient.get).mockResolvedValue({
|
|
954
|
-
document: mockDocument,
|
|
955
|
-
childIds: [],
|
|
956
|
-
});
|
|
957
|
-
vi.mocked(mockReactorClient.getDocumentModels).mockResolvedValue({
|
|
958
|
-
results: [mockModule],
|
|
959
|
-
options: { cursor: "", limit: 10 },
|
|
960
|
-
});
|
|
961
|
-
vi.mocked(mockReactorClient.execute).mockRejectedValue(new Error("Mutation failed"));
|
|
962
|
-
await expect(resolvers.mutateDocument(mockReactorClient, {
|
|
963
|
-
documentIdentifier: "doc-1",
|
|
964
|
-
actions: mockActions,
|
|
965
|
-
view: null,
|
|
966
|
-
})).rejects.toThrow("Failed to mutate document: Mutation failed");
|
|
242
|
+
expect(result.id).toBe(testDoc.header.id);
|
|
967
243
|
});
|
|
968
244
|
});
|
|
969
|
-
describe("
|
|
970
|
-
it("should
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
input: { name: "New Name" },
|
|
977
|
-
id: "action-1",
|
|
978
|
-
timestampUtcMs: "2024-01-01T00:00:00Z",
|
|
979
|
-
},
|
|
980
|
-
];
|
|
981
|
-
const mockModule = {
|
|
982
|
-
documentModel: {
|
|
983
|
-
global: {
|
|
984
|
-
name: "powerhouse/document-model",
|
|
985
|
-
specifications: [
|
|
986
|
-
{
|
|
987
|
-
modules: [
|
|
988
|
-
{
|
|
989
|
-
operations: [{ name: "SET_NAME", scope: "global" }],
|
|
990
|
-
},
|
|
991
|
-
],
|
|
992
|
-
},
|
|
993
|
-
],
|
|
994
|
-
},
|
|
995
|
-
},
|
|
996
|
-
actions: {
|
|
997
|
-
setName: vi.fn((input) => mockActions[0]),
|
|
998
|
-
},
|
|
999
|
-
};
|
|
1000
|
-
const mockJobInfo = {
|
|
1001
|
-
id: "job-123",
|
|
1002
|
-
status: JobStatus.PENDING,
|
|
1003
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
1004
|
-
consistencyToken: {
|
|
1005
|
-
version: 1,
|
|
1006
|
-
createdAtUtcIso: "2024-01-01T00:00:00Z",
|
|
1007
|
-
coordinates: [],
|
|
1008
|
-
},
|
|
1009
|
-
};
|
|
1010
|
-
vi.mocked(mockReactorClient.get).mockResolvedValue({
|
|
1011
|
-
document: mockDocument,
|
|
1012
|
-
childIds: [],
|
|
1013
|
-
});
|
|
1014
|
-
vi.mocked(mockReactorClient.getDocumentModels).mockResolvedValue({
|
|
1015
|
-
results: [mockModule],
|
|
1016
|
-
options: { cursor: "", limit: 10 },
|
|
1017
|
-
});
|
|
1018
|
-
vi.mocked(mockReactorClient.executeAsync).mockResolvedValue(mockJobInfo);
|
|
1019
|
-
const result = await resolvers.mutateDocumentAsync(mockReactorClient, {
|
|
1020
|
-
documentIdentifier: "doc-1",
|
|
1021
|
-
actions: mockActions,
|
|
1022
|
-
view: { branch: "develop", scopes: null },
|
|
1023
|
-
});
|
|
1024
|
-
expect(mockReactorClient.executeAsync).toHaveBeenCalledWith("doc-1", "develop", mockActions);
|
|
1025
|
-
expect(result).toBe("job-123");
|
|
245
|
+
describe("Error Handling", () => {
|
|
246
|
+
it("should handle rename errors", async () => {
|
|
247
|
+
await expect(resolvers.renameDocument(module.client, {
|
|
248
|
+
documentIdentifier: "non-existent-id",
|
|
249
|
+
name: "New Name",
|
|
250
|
+
branch: null,
|
|
251
|
+
})).rejects.toThrow();
|
|
1026
252
|
});
|
|
1027
|
-
it("should handle
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
scope: "global",
|
|
1033
|
-
input: { name: "New Name" },
|
|
1034
|
-
id: "action-1",
|
|
1035
|
-
timestampUtcMs: "2024-01-01T00:00:00Z",
|
|
1036
|
-
},
|
|
1037
|
-
];
|
|
1038
|
-
const mockModule = {
|
|
1039
|
-
documentModel: {
|
|
1040
|
-
global: {
|
|
1041
|
-
name: "powerhouse/document-model",
|
|
1042
|
-
specifications: [
|
|
1043
|
-
{
|
|
1044
|
-
modules: [
|
|
1045
|
-
{
|
|
1046
|
-
operations: [{ name: "SET_NAME", scope: "global" }],
|
|
1047
|
-
},
|
|
1048
|
-
],
|
|
1049
|
-
},
|
|
1050
|
-
],
|
|
1051
|
-
},
|
|
1052
|
-
},
|
|
1053
|
-
actions: {
|
|
1054
|
-
setName: vi.fn((input) => mockActions[0]),
|
|
1055
|
-
},
|
|
1056
|
-
};
|
|
1057
|
-
vi.mocked(mockReactorClient.get).mockResolvedValue({
|
|
1058
|
-
document: mockDocument,
|
|
1059
|
-
childIds: [],
|
|
1060
|
-
});
|
|
1061
|
-
vi.mocked(mockReactorClient.getDocumentModels).mockResolvedValue({
|
|
1062
|
-
results: [mockModule],
|
|
1063
|
-
options: { cursor: "", limit: 10 },
|
|
1064
|
-
});
|
|
1065
|
-
vi.mocked(mockReactorClient.executeAsync).mockRejectedValue(new Error("Queue full"));
|
|
1066
|
-
await expect(resolvers.mutateDocumentAsync(mockReactorClient, {
|
|
1067
|
-
documentIdentifier: "doc-1",
|
|
1068
|
-
actions: mockActions,
|
|
1069
|
-
view: null,
|
|
1070
|
-
})).rejects.toThrow("Failed to submit document mutation: Queue full");
|
|
253
|
+
it("should handle delete errors", async () => {
|
|
254
|
+
await expect(resolvers.deleteDocument(module.client, {
|
|
255
|
+
identifier: "non-existent-id",
|
|
256
|
+
propagate: null,
|
|
257
|
+
})).rejects.toThrow();
|
|
1071
258
|
});
|
|
1072
259
|
});
|
|
1073
260
|
});
|