@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.
Files changed (39) hide show
  1. package/dist/src/graphql/graphql-manager.d.ts.map +1 -1
  2. package/dist/src/graphql/graphql-manager.js +2 -4
  3. package/dist/src/graphql/graphql-manager.js.map +1 -1
  4. package/dist/src/graphql/index.d.ts +0 -1
  5. package/dist/src/graphql/index.d.ts.map +1 -1
  6. package/dist/src/graphql/index.js +0 -1
  7. package/dist/src/graphql/index.js.map +1 -1
  8. package/dist/src/graphql/reactor/adapters.d.ts +2 -2
  9. package/dist/src/graphql/reactor/adapters.d.ts.map +1 -1
  10. package/dist/src/graphql/reactor/adapters.js +2 -2
  11. package/dist/src/graphql/reactor/adapters.js.map +1 -1
  12. package/dist/src/graphql/reactor/resolvers.d.ts.map +1 -1
  13. package/dist/src/graphql/reactor/resolvers.js +4 -6
  14. package/dist/src/graphql/reactor/resolvers.js.map +1 -1
  15. package/dist/src/graphql/reactor/subgraph.d.ts.map +1 -1
  16. package/dist/src/graphql/reactor/subgraph.js +0 -9
  17. package/dist/src/graphql/reactor/subgraph.js.map +1 -1
  18. package/dist/src/graphql/reactor/validation.d.ts +4 -4
  19. package/dist/src/server.d.ts.map +1 -1
  20. package/dist/src/server.js +2 -1
  21. package/dist/src/server.js.map +1 -1
  22. package/dist/src/tracing.d.ts +2 -108
  23. package/dist/src/tracing.d.ts.map +1 -1
  24. package/dist/src/tracing.js +115 -252
  25. package/dist/src/tracing.js.map +1 -1
  26. package/dist/test/permissions-integration.test.js +1 -1
  27. package/dist/test/permissions-integration.test.js.map +1 -1
  28. package/dist/test/reactor-adapters.test.js +30 -137
  29. package/dist/test/reactor-adapters.test.js.map +1 -1
  30. package/dist/test/reactor-resolvers.test.js +157 -970
  31. package/dist/test/reactor-resolvers.test.js.map +1 -1
  32. package/dist/test/reactor-subgraph-permissions.test.js +1 -1
  33. package/dist/test/reactor-subgraph-permissions.test.js.map +1 -1
  34. package/dist/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +13 -8
  36. package/dist/src/graphql/datadog-plugin.d.ts +0 -14
  37. package/dist/src/graphql/datadog-plugin.d.ts.map +0 -1
  38. package/dist/src/graphql/datadog-plugin.js +0 -103
  39. package/dist/src/graphql/datadog-plugin.js.map +0 -1
@@ -1,1073 +1,260 @@
1
- import { JobStatus, } from "@powerhousedao/reactor";
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, vi } from "vitest";
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 mockReactorClient;
7
- beforeEach(() => {
8
- vi.clearAllMocks();
9
- // Create fresh mock for each test
10
- mockReactorClient = {
11
- getDocumentModels: vi.fn(),
12
- get: vi.fn(),
13
- getChildren: vi.fn(),
14
- getParents: vi.fn(),
15
- find: vi.fn(),
16
- getJobStatus: vi.fn(),
17
- waitForJob: vi.fn(),
18
- create: vi.fn(),
19
- createEmpty: vi.fn(),
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 mockDocumentModels = {
34
- results: [
35
- documentModelDocumentModelModule,
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 extract namespace from model name", async () => {
65
- const mockDocumentModels = {
66
- results: [
67
- {
68
- documentModel: {
69
- global: {
70
- id: "model-1",
71
- name: "custom-namespace/my-model",
72
- author: { name: "Author", website: null },
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 mockDocument = {
91
- header: {
92
- id: "doc-1",
93
- name: "Test Document",
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
- const result = await resolvers.document(mockReactorClient, {
120
- identifier: "doc-1",
121
- });
122
- expect(result).toEqual({
123
- document: {
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 mockChildren = {
175
- results: [
176
- {
177
- header: {
178
- id: "child-1",
179
- name: "Child 1",
180
- documentType: "type-1",
181
- slug: "child-1",
182
- createdAtUtcIso: "2024-01-01T00:00:00Z",
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.cursor).toBeNull();
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 mockParents = {
278
- results: [
279
- {
280
- header: {
281
- id: "parent-1",
282
- name: "Parent 1",
283
- documentType: "folder",
284
- slug: "parent-1",
285
- createdAtUtcIso: "2024-01-01T00:00:00Z",
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 transform found documents to GraphQL format", async () => {
336
- const mockDocuments = {
337
- results: [
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: "parent-1",
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
- vi.mocked(mockReactorClient.getJobStatus).mockResolvedValue(mockJobInfo);
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.completedAt).toBeNull();
518
- expect(result.error).toBeNull();
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 handling", () => {
523
- it("should wrap ReactorClient errors with descriptive messages", async () => {
524
- vi.mocked(mockReactorClient.getDocumentModels).mockRejectedValue(new Error("Network timeout"));
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 mockReactorClient;
545
- const createMockDocument = (overrides = {}) => ({
546
- header: {
547
- id: "doc-1",
548
- name: "Test Document",
549
- documentType: "powerhouse/document-model",
550
- slug: "test-doc",
551
- createdAtUtcIso: "2024-01-01T00:00:00Z",
552
- lastModifiedAtUtcIso: "2024-01-02T00:00:00Z",
553
- branch: "main",
554
- sig: {
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
- beforeEach(() => {
568
- vi.clearAllMocks();
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 = createMockDocument();
593
- const createdDocument = createMockDocument({
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(mockReactorClient.create).toHaveBeenCalledWith(inputDocument, undefined);
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(mockReactorClient, {
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(mockReactorClient, {
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 emptyDocument = createMockDocument();
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(mockReactorClient.createEmpty).toHaveBeenCalledWith("powerhouse/document-model", undefined);
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 renamedDocument = createMockDocument({
671
- header: {
672
- ...createMockDocument().header,
673
- name: "New Name",
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(mockReactorClient.rename).toHaveBeenCalledWith("doc-1", "New Name", undefined);
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 parentDocument = createMockDocument();
707
- vi.mocked(mockReactorClient.addChildren).mockResolvedValue(parentDocument);
708
- const result = await resolvers.addChildren(mockReactorClient, {
709
- parentIdentifier: "parent-1",
710
- documentIdentifiers: ["child-1", "child-2"],
711
- branch: "main",
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
- })).rejects.toThrow("Failed to add children: Child not found");
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 parentDocument = createMockDocument();
728
- vi.mocked(mockReactorClient.removeChildren).mockResolvedValue(parentDocument);
729
- const result = await resolvers.removeChildren(mockReactorClient, {
730
- parentIdentifier: "parent-1",
731
- documentIdentifiers: ["child-1", "child-2"],
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(mockReactorClient.removeChildren).toHaveBeenCalledWith("parent-1", ["child-1", "child-2"], undefined);
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 without propagation", async () => {
779
- vi.mocked(mockReactorClient.deleteDocument).mockResolvedValue();
780
- const result = await resolvers.deleteDocument(mockReactorClient, {
781
- identifier: "doc-1",
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
- vi.mocked(mockReactorClient.deleteDocuments).mockResolvedValue();
807
- const result = await resolvers.deleteDocuments(mockReactorClient, {
808
- identifiers: ["doc-1", "doc-2", "doc-3"],
809
- propagate: "ORPHAN",
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 mockDocument = createMockDocument();
825
- const mockActions = [
826
- {
827
- type: "SET_NAME",
828
- scope: "global",
829
- input: { name: "New Name" },
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 mockModule = {
835
- documentModel: {
836
- global: {
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(mockReactorClient.execute).toHaveBeenCalledWith("doc-1", "main", mockActions);
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("mutateDocumentAsync", () => {
970
- it("should submit actions asynchronously and return job ID", async () => {
971
- const mockDocument = createMockDocument();
972
- const mockActions = [
973
- {
974
- type: "SET_NAME",
975
- scope: "global",
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 async mutation errors", async () => {
1028
- const mockDocument = createMockDocument();
1029
- const mockActions = [
1030
- {
1031
- type: "SET_NAME",
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
  });