@powerhousedao/vetra 4.1.0-dev.81 → 4.1.0-dev.83

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 (60) hide show
  1. package/dist/document-models/app-module/src/reducers/base-operations.d.ts.map +1 -1
  2. package/dist/document-models/app-module/src/reducers/base-operations.js +5 -1
  3. package/dist/document-models/app-module/src/tests/base-operations.test.js +157 -30
  4. package/dist/document-models/app-module/src/tests/dnd-operations.test.js +38 -7
  5. package/dist/document-models/app-module/src/tests/document-model.test.js +80 -8
  6. package/dist/document-models/document-editor/src/reducers/base-operations.d.ts.map +1 -1
  7. package/dist/document-models/document-editor/src/reducers/base-operations.js +10 -1
  8. package/dist/document-models/document-editor/src/tests/base-operations.test.js +137 -23
  9. package/dist/document-models/document-editor/src/tests/document-model.test.js +91 -8
  10. package/dist/document-models/processor-module/src/reducers/base-operations.d.ts.map +1 -1
  11. package/dist/document-models/processor-module/src/reducers/base-operations.js +15 -2
  12. package/dist/document-models/processor-module/src/tests/base-operations.test.js +153 -33
  13. package/dist/document-models/processor-module/src/tests/document-model.test.js +96 -8
  14. package/dist/document-models/subgraph-module/src/reducers/base-operations.d.ts.map +1 -1
  15. package/dist/document-models/subgraph-module/src/reducers/base-operations.js +5 -1
  16. package/dist/document-models/subgraph-module/src/tests/base-operations.test.js +33 -12
  17. package/dist/document-models/subgraph-module/src/tests/document-model.test.js +25 -8
  18. package/dist/document-models/vetra-package/src/reducers/base-operations.d.ts.map +1 -1
  19. package/dist/document-models/vetra-package/src/reducers/base-operations.js +5 -0
  20. package/dist/document-models/vetra-package/src/tests/base-operations.test.js +171 -75
  21. package/dist/document-models/vetra-package/src/tests/document-model.test.js +101 -8
  22. package/dist/editors/app-editor/components/AppEditorForm.d.ts.map +1 -1
  23. package/dist/editors/app-editor/components/AppEditorForm.js +2 -2
  24. package/dist/editors/app-editor/editor.test.d.ts +2 -0
  25. package/dist/editors/app-editor/editor.test.d.ts.map +1 -0
  26. package/dist/editors/app-editor/editor.test.js +422 -0
  27. package/dist/editors/document-editor/components/DocumentEditorForm.d.ts.map +1 -1
  28. package/dist/editors/document-editor/components/DocumentEditorForm.js +1 -1
  29. package/dist/editors/document-editor/editor.test.d.ts +2 -0
  30. package/dist/editors/document-editor/editor.test.d.ts.map +1 -0
  31. package/dist/editors/document-editor/editor.test.js +374 -0
  32. package/dist/editors/processor-editor/components/ProcessorEditorForm.d.ts.map +1 -1
  33. package/dist/editors/processor-editor/components/ProcessorEditorForm.js +1 -1
  34. package/dist/editors/processor-editor/editor.test.d.ts +2 -0
  35. package/dist/editors/processor-editor/editor.test.d.ts.map +1 -0
  36. package/dist/editors/processor-editor/editor.test.js +459 -0
  37. package/dist/editors/subgraph-editor/components/SubgraphEditorForm.d.ts.map +1 -1
  38. package/dist/editors/subgraph-editor/components/SubgraphEditorForm.js +3 -3
  39. package/dist/editors/subgraph-editor/editor.test.d.ts +2 -0
  40. package/dist/editors/subgraph-editor/editor.test.d.ts.map +1 -0
  41. package/dist/editors/subgraph-editor/editor.test.js +201 -0
  42. package/dist/editors/vetra-package/components/MetaForm.d.ts.map +1 -1
  43. package/dist/editors/vetra-package/components/MetaForm.js +3 -3
  44. package/dist/editors/vetra-package/editor.test.d.ts +2 -0
  45. package/dist/editors/vetra-package/editor.test.d.ts.map +1 -0
  46. package/dist/editors/vetra-package/editor.test.js +330 -0
  47. package/dist/processors/codegen/__tests__/codegen-processor-e2e.test.d.ts +2 -0
  48. package/dist/processors/codegen/__tests__/codegen-processor-e2e.test.d.ts.map +1 -0
  49. package/dist/processors/codegen/__tests__/codegen-processor-e2e.test.js +615 -0
  50. package/dist/processors/codegen/__tests__/factory.test.d.ts +2 -0
  51. package/dist/processors/codegen/__tests__/factory.test.d.ts.map +1 -0
  52. package/dist/processors/codegen/__tests__/factory.test.js +190 -0
  53. package/dist/setupTests.d.ts +2 -0
  54. package/dist/setupTests.d.ts.map +1 -0
  55. package/dist/setupTests.js +1 -0
  56. package/dist/style.css +9 -0
  57. package/dist/tsconfig.tsbuildinfo +1 -1
  58. package/dist/vitest.config.d.ts.map +1 -1
  59. package/dist/vitest.config.js +9 -0
  60. package/package.json +19 -14
@@ -2,17 +2,100 @@
2
2
  * This is a scaffold file meant for customization:
3
3
  * - change it by adding new tests or modifying the existing ones
4
4
  */
5
- import { describe, it, expect, beforeEach } from "vitest";
6
- import utils, { initialGlobalState, initialLocalState, } from "../../gen/utils.js";
5
+ import { describe, expect, it } from "vitest";
6
+ import * as creators from "../../gen/base-operations/creators.js";
7
+ import { reducer } from "../../gen/reducer.js";
8
+ import utils from "../../gen/utils.js";
7
9
  describe("Document Editor Document Model", () => {
8
- it("should create a new Document Editor document", () => {
10
+ it("should have correct initial values", () => {
9
11
  const document = utils.createDocument();
10
- expect(document).toBeDefined();
11
- expect(document.header.documentType).toBe("powerhouse/document-editor");
12
+ expect(document.state.global.name).toBe("");
13
+ expect(document.state.global.documentTypes).toEqual([]);
14
+ expect(document.state.global.status).toBe("DRAFT");
12
15
  });
13
- it("should create a new Document Editor document with a valid initial state", () => {
16
+ it("should handle multiple operations and maintain consistency", () => {
14
17
  const document = utils.createDocument();
15
- expect(document.state.global).toStrictEqual(initialGlobalState);
16
- expect(document.state.local).toStrictEqual(initialLocalState);
18
+ let updatedDoc = reducer(document, creators.setEditorName({ name: "Test Editor" }));
19
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
20
+ id: "test-type",
21
+ documentType: "powerhouse/test",
22
+ }));
23
+ updatedDoc = reducer(updatedDoc, creators.setEditorStatus({ status: "CONFIRMED" }));
24
+ // Verify state consistency
25
+ expect(updatedDoc.state.global.name).toBe("Test Editor");
26
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(1);
27
+ expect(updatedDoc.state.global.status).toBe("CONFIRMED");
28
+ });
29
+ describe("Complex Scenarios", () => {
30
+ it("should handle workflow: set name, add types, confirm status", () => {
31
+ const document = utils.createDocument();
32
+ // Step 1: Set editor name
33
+ let updatedDoc = reducer(document, creators.setEditorName({ name: "Production Editor" }));
34
+ expect(updatedDoc.state.global.name).toBe("Production Editor");
35
+ // Step 2: Add document types
36
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
37
+ id: "budget-docs",
38
+ documentType: "powerhouse/budget",
39
+ }));
40
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
41
+ id: "invoice-docs",
42
+ documentType: "powerhouse/invoice",
43
+ }));
44
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(2);
45
+ // Step 3: Confirm editor status
46
+ updatedDoc = reducer(updatedDoc, creators.setEditorStatus({ status: "CONFIRMED" }));
47
+ expect(updatedDoc.state.global.status).toBe("CONFIRMED");
48
+ });
49
+ it("should handle reset scenario: remove all types and add new ones", () => {
50
+ const document = utils.createDocument();
51
+ // Add initial types
52
+ let updatedDoc = reducer(document, creators.addDocumentType({
53
+ id: "old-type-1",
54
+ documentType: "powerhouse/old1",
55
+ }));
56
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
57
+ id: "old-type-2",
58
+ documentType: "powerhouse/old2",
59
+ }));
60
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(2);
61
+ // Remove all types
62
+ updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "old-type-1" }));
63
+ updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "old-type-2" }));
64
+ expect(updatedDoc.state.global.documentTypes).toEqual([]);
65
+ // Add new types from scratch
66
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
67
+ id: "new-type-1",
68
+ documentType: "powerhouse/new1",
69
+ }));
70
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
71
+ id: "new-type-2",
72
+ documentType: "powerhouse/new2",
73
+ }));
74
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
75
+ id: "new-type-3",
76
+ documentType: "powerhouse/new3",
77
+ }));
78
+ // Verify reset completed
79
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(3);
80
+ expect(updatedDoc.state.global.documentTypes.find((dt) => dt.id === "old-type-1")).toBeUndefined();
81
+ expect(updatedDoc.state.global.documentTypes.find((dt) => dt.id === "new-type-1")).toBeDefined();
82
+ });
83
+ it("should maintain state integrity with complex add/remove sequences", () => {
84
+ const document = utils.createDocument();
85
+ // Add multiple types
86
+ let updatedDoc = reducer(document, creators.addDocumentType({ id: "type-a", documentType: "a" }));
87
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({ id: "type-b", documentType: "b" }));
88
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({ id: "type-c", documentType: "c" }));
89
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(3);
90
+ // Remove middle one
91
+ updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "type-b" }));
92
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(2);
93
+ // Add it back with new documentType
94
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({ id: "type-b", documentType: "b-new" }));
95
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(3);
96
+ // Verify order and content
97
+ const typeB = updatedDoc.state.global.documentTypes.find((dt) => dt.id === "type-b");
98
+ expect(typeB?.documentType).toBe("b-new");
99
+ });
17
100
  });
18
101
  });
@@ -1 +1 @@
1
- {"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../document-models/processor-module/src/reducers/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,yCAAyC,CAAC;AAEvG,eAAO,MAAM,OAAO,EAAE,uCAqBrB,CAAC"}
1
+ {"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../document-models/processor-module/src/reducers/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,yCAAyC,CAAC;AAEvG,eAAO,MAAM,OAAO,EAAE,uCAuCrB,CAAC"}
@@ -1,11 +1,24 @@
1
1
  export const reducer = {
2
2
  setProcessorNameOperation(state, action, dispatch) {
3
- state.name = action.input.name;
3
+ const trimmedName = action.input.name.trim();
4
+ if (trimmedName === "") {
5
+ throw new Error("Processor name cannot be empty");
6
+ }
7
+ state.name = trimmedName;
4
8
  },
5
9
  setProcessorTypeOperation(state, action, dispatch) {
6
- state.type = action.input.type;
10
+ const trimmedType = action.input.type.trim();
11
+ if (trimmedType === "") {
12
+ throw new Error("Processor type cannot be empty");
13
+ }
14
+ state.type = trimmedType;
7
15
  },
8
16
  addDocumentTypeOperation(state, action, dispatch) {
17
+ // Check for duplicate ID
18
+ const existingId = state.documentTypes.find((dt) => dt.id === action.input.id);
19
+ if (existingId) {
20
+ throw new Error(`Document type with id "${action.input.id}" already exists`);
21
+ }
9
22
  state.documentTypes.push({
10
23
  id: action.input.id,
11
24
  documentType: action.input.documentType,
@@ -2,47 +2,167 @@
2
2
  * This is a scaffold file meant for customization:
3
3
  * - change it by adding new tests or modifying the existing ones
4
4
  */
5
- import { describe, it, expect, beforeEach } from "vitest";
6
- import { generateMock } from "@powerhousedao/codegen";
7
- import utils from "../../gen/utils.js";
8
- import { z } from "../../gen/schema/index.js";
9
- import { reducer } from "../../gen/reducer.js";
5
+ import { beforeEach, describe, expect, it } from "vitest";
10
6
  import * as creators from "../../gen/base-operations/creators.js";
7
+ import { reducer } from "../../gen/reducer.js";
8
+ import utils from "../../gen/utils.js";
11
9
  describe("BaseOperations Operations", () => {
12
10
  let document;
13
11
  beforeEach(() => {
14
12
  document = utils.createDocument();
15
13
  });
16
- it("should handle setProcessorName operation", () => {
17
- const input = generateMock(z.SetProcessorNameInputSchema());
18
- const updatedDocument = reducer(document, creators.setProcessorName(input));
19
- expect(updatedDocument.operations.global).toHaveLength(1);
20
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_PROCESSOR_NAME");
21
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
22
- expect(updatedDocument.operations.global[0].index).toEqual(0);
14
+ describe("setProcessorName", () => {
15
+ it("should mutate state with new name", () => {
16
+ const input = { name: "My Processor" };
17
+ const updatedDocument = reducer(document, creators.setProcessorName(input));
18
+ expect(updatedDocument.state.global.name).toBe("My Processor");
19
+ });
20
+ it("should reject empty string and store error in operation", () => {
21
+ const input = { name: "" };
22
+ const updatedDocument = reducer(document, creators.setProcessorName(input));
23
+ expect(updatedDocument.operations.global).toHaveLength(1);
24
+ expect(updatedDocument.operations.global[0].error).toBe("Processor name cannot be empty");
25
+ expect(updatedDocument.state.global.name).toBe("");
26
+ });
27
+ });
28
+ describe("setProcessorType", () => {
29
+ it("should mutate state with new type", () => {
30
+ const input = { type: "analytics" };
31
+ const updatedDocument = reducer(document, creators.setProcessorType(input));
32
+ expect(updatedDocument.state.global.type).toBe("analytics");
33
+ });
34
+ it("should reject empty string and store error in operation", () => {
35
+ const input = { type: "" };
36
+ const updatedDocument = reducer(document, creators.setProcessorType(input));
37
+ expect(updatedDocument.operations.global).toHaveLength(1);
38
+ expect(updatedDocument.operations.global[0].error).toBe("Processor type cannot be empty");
39
+ expect(updatedDocument.state.global.type).toBe("");
40
+ });
23
41
  });
24
- it("should handle setProcessorType operation", () => {
25
- const input = generateMock(z.SetProcessorTypeInputSchema());
26
- const updatedDocument = reducer(document, creators.setProcessorType(input));
27
- expect(updatedDocument.operations.global).toHaveLength(1);
28
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_PROCESSOR_TYPE");
29
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
30
- expect(updatedDocument.operations.global[0].index).toEqual(0);
42
+ describe("setProcessorStatus", () => {
43
+ it("should mutate state with new status", () => {
44
+ const input = { status: "CONFIRMED" };
45
+ const updatedDocument = reducer(document, creators.setProcessorStatus(input));
46
+ expect(updatedDocument.state.global.status).toBe("CONFIRMED");
47
+ });
48
+ it("should transition from DRAFT to CONFIRMED", () => {
49
+ expect(document.state.global.status).toBe("DRAFT");
50
+ const updatedDocument = reducer(document, creators.setProcessorStatus({ status: "CONFIRMED" }));
51
+ expect(updatedDocument.state.global.status).toBe("CONFIRMED");
52
+ });
53
+ it("should transition from CONFIRMED to DRAFT", () => {
54
+ const confirmedDoc = reducer(document, creators.setProcessorStatus({ status: "CONFIRMED" }));
55
+ const updatedDocument = reducer(confirmedDoc, creators.setProcessorStatus({ status: "DRAFT" }));
56
+ expect(updatedDocument.state.global.status).toBe("DRAFT");
57
+ });
31
58
  });
32
- it("should handle addDocumentType operation", () => {
33
- const input = generateMock(z.AddDocumentTypeInputSchema());
34
- const updatedDocument = reducer(document, creators.addDocumentType(input));
35
- expect(updatedDocument.operations.global).toHaveLength(1);
36
- expect(updatedDocument.operations.global[0].action.type).toBe("ADD_DOCUMENT_TYPE");
37
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
38
- expect(updatedDocument.operations.global[0].index).toEqual(0);
59
+ describe("addDocumentType", () => {
60
+ it("should mutate state by adding document type to array", () => {
61
+ const input = {
62
+ id: "test-type-1",
63
+ documentType: "powerhouse/test",
64
+ };
65
+ const updatedDocument = reducer(document, creators.addDocumentType(input));
66
+ expect(updatedDocument.state.global.documentTypes).toContainEqual({
67
+ id: "test-type-1",
68
+ documentType: "powerhouse/test",
69
+ });
70
+ });
71
+ it("should add to empty array from initial state", () => {
72
+ expect(document.state.global.documentTypes).toEqual([]);
73
+ const input = {
74
+ id: "first-type",
75
+ documentType: "powerhouse/first",
76
+ };
77
+ const updatedDocument = reducer(document, creators.addDocumentType(input));
78
+ expect(updatedDocument.state.global.documentTypes).toEqual([
79
+ { id: "first-type", documentType: "powerhouse/first" },
80
+ ]);
81
+ });
82
+ it("should add multiple document types sequentially", () => {
83
+ let updatedDoc = reducer(document, creators.addDocumentType({
84
+ id: "type-1",
85
+ documentType: "powerhouse/a",
86
+ }));
87
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
88
+ id: "type-2",
89
+ documentType: "powerhouse/b",
90
+ }));
91
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
92
+ id: "type-3",
93
+ documentType: "powerhouse/c",
94
+ }));
95
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(3);
96
+ expect(updatedDoc.state.global.documentTypes[0]).toEqual({
97
+ id: "type-1",
98
+ documentType: "powerhouse/a",
99
+ });
100
+ expect(updatedDoc.state.global.documentTypes[1]).toEqual({
101
+ id: "type-2",
102
+ documentType: "powerhouse/b",
103
+ });
104
+ expect(updatedDoc.state.global.documentTypes[2]).toEqual({
105
+ id: "type-3",
106
+ documentType: "powerhouse/c",
107
+ });
108
+ });
109
+ it("should reject duplicate IDs and store error in operation", () => {
110
+ const input = {
111
+ id: "duplicate",
112
+ documentType: "powerhouse/first",
113
+ };
114
+ let updatedDoc = reducer(document, creators.addDocumentType(input));
115
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(1);
116
+ expect(updatedDoc.operations.global[0].error).toBeUndefined();
117
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
118
+ id: "duplicate",
119
+ documentType: "powerhouse/second",
120
+ }));
121
+ expect(updatedDoc.operations.global).toHaveLength(2);
122
+ expect(updatedDoc.operations.global[1].error).toBe('Document type with id "duplicate" already exists');
123
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(1);
124
+ });
39
125
  });
40
- it("should handle removeDocumentType operation", () => {
41
- const input = generateMock(z.RemoveDocumentTypeInputSchema());
42
- const updatedDocument = reducer(document, creators.removeDocumentType(input));
43
- expect(updatedDocument.operations.global).toHaveLength(1);
44
- expect(updatedDocument.operations.global[0].action.type).toBe("REMOVE_DOCUMENT_TYPE");
45
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
46
- expect(updatedDocument.operations.global[0].index).toEqual(0);
126
+ describe("removeDocumentType", () => {
127
+ it("should mutate state by removing document type from array", () => {
128
+ let updatedDoc = reducer(document, creators.addDocumentType({
129
+ id: "to-remove",
130
+ documentType: "powerhouse/test",
131
+ }));
132
+ updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "to-remove" }));
133
+ expect(updatedDoc.state.global.documentTypes).not.toContainEqual({
134
+ id: "to-remove",
135
+ documentType: "powerhouse/test",
136
+ });
137
+ });
138
+ it("should remove existing ID", () => {
139
+ let updatedDoc = reducer(document, creators.addDocumentType({
140
+ id: "existing",
141
+ documentType: "powerhouse/test",
142
+ }));
143
+ const lengthBefore = updatedDoc.state.global.documentTypes.length;
144
+ updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "existing" }));
145
+ expect(updatedDoc.state.global.documentTypes.length).toBe(lengthBefore - 1);
146
+ expect(updatedDoc.state.global.documentTypes.find((dt) => dt.id === "existing")).toBeUndefined();
147
+ });
148
+ it("should gracefully handle non-existent ID", () => {
149
+ const initialState = document.state.global.documentTypes;
150
+ const updatedDocument = reducer(document, creators.removeDocumentType({ id: "non-existent-id" }));
151
+ expect(updatedDocument.state.global.documentTypes).toEqual(initialState);
152
+ });
153
+ it("should handle empty array gracefully", () => {
154
+ expect(document.state.global.documentTypes).toEqual([]);
155
+ const updatedDocument = reducer(document, creators.removeDocumentType({ id: "any-id" }));
156
+ expect(updatedDocument.state.global.documentTypes).toEqual([]);
157
+ });
158
+ it("should add then immediately remove item", () => {
159
+ let updatedDoc = reducer(document, creators.addDocumentType({
160
+ id: "temp-type",
161
+ documentType: "powerhouse/temp",
162
+ }));
163
+ updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "temp-type" }));
164
+ expect(updatedDoc.state.global.documentTypes.find((dt) => dt.id === "temp-type")).toBeUndefined();
165
+ expect(updatedDoc.operations.global).toHaveLength(2);
166
+ });
47
167
  });
48
168
  });
@@ -2,17 +2,105 @@
2
2
  * This is a scaffold file meant for customization:
3
3
  * - change it by adding new tests or modifying the existing ones
4
4
  */
5
- import { describe, it, expect, beforeEach } from "vitest";
6
- import utils, { initialGlobalState, initialLocalState, } from "../../gen/utils.js";
5
+ import { describe, expect, it } from "vitest";
6
+ import * as creators from "../../gen/base-operations/creators.js";
7
+ import { reducer } from "../../gen/reducer.js";
8
+ import utils from "../../gen/utils.js";
7
9
  describe("Processor Module Document Model", () => {
8
- it("should create a new Processor Module document", () => {
10
+ it("should have correct initial values", () => {
9
11
  const document = utils.createDocument();
10
- expect(document).toBeDefined();
11
- expect(document.header.documentType).toBe("powerhouse/processor");
12
+ expect(document.state.global.name).toBe("");
13
+ expect(document.state.global.type).toBe("");
14
+ expect(document.state.global.documentTypes).toEqual([]);
15
+ expect(document.state.global.status).toBe("DRAFT");
12
16
  });
13
- it("should create a new Processor Module document with a valid initial state", () => {
17
+ it("should handle multiple operations and maintain consistency", () => {
14
18
  const document = utils.createDocument();
15
- expect(document.state.global).toStrictEqual(initialGlobalState);
16
- expect(document.state.local).toStrictEqual(initialLocalState);
19
+ let updatedDoc = reducer(document, creators.setProcessorName({ name: "Test Processor" }));
20
+ updatedDoc = reducer(updatedDoc, creators.setProcessorType({ type: "analytics" }));
21
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
22
+ id: "test-type",
23
+ documentType: "powerhouse/test",
24
+ }));
25
+ updatedDoc = reducer(updatedDoc, creators.setProcessorStatus({ status: "CONFIRMED" }));
26
+ // Verify state consistency
27
+ expect(updatedDoc.state.global.name).toBe("Test Processor");
28
+ expect(updatedDoc.state.global.type).toBe("analytics");
29
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(1);
30
+ expect(updatedDoc.state.global.status).toBe("CONFIRMED");
31
+ });
32
+ describe("Complex Scenarios", () => {
33
+ it("should handle workflow: set name/type, add types, confirm status", () => {
34
+ const document = utils.createDocument();
35
+ // Step 1: Set processor name and type
36
+ let updatedDoc = reducer(document, creators.setProcessorName({ name: "Production Processor" }));
37
+ expect(updatedDoc.state.global.name).toBe("Production Processor");
38
+ updatedDoc = reducer(updatedDoc, creators.setProcessorType({ type: "data-analytics" }));
39
+ expect(updatedDoc.state.global.type).toBe("data-analytics");
40
+ // Step 2: Add document types
41
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
42
+ id: "budget-docs",
43
+ documentType: "powerhouse/budget",
44
+ }));
45
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
46
+ id: "invoice-docs",
47
+ documentType: "powerhouse/invoice",
48
+ }));
49
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(2);
50
+ // Step 3: Confirm processor status
51
+ updatedDoc = reducer(updatedDoc, creators.setProcessorStatus({ status: "CONFIRMED" }));
52
+ expect(updatedDoc.state.global.status).toBe("CONFIRMED");
53
+ });
54
+ it("should handle reset scenario: remove all types and add new ones", () => {
55
+ const document = utils.createDocument();
56
+ // Add initial types
57
+ let updatedDoc = reducer(document, creators.addDocumentType({
58
+ id: "old-type-1",
59
+ documentType: "powerhouse/old1",
60
+ }));
61
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
62
+ id: "old-type-2",
63
+ documentType: "powerhouse/old2",
64
+ }));
65
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(2);
66
+ // Remove all types
67
+ updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "old-type-1" }));
68
+ updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "old-type-2" }));
69
+ expect(updatedDoc.state.global.documentTypes).toEqual([]);
70
+ // Add new types from scratch
71
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
72
+ id: "new-type-1",
73
+ documentType: "powerhouse/new1",
74
+ }));
75
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
76
+ id: "new-type-2",
77
+ documentType: "powerhouse/new2",
78
+ }));
79
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({
80
+ id: "new-type-3",
81
+ documentType: "powerhouse/new3",
82
+ }));
83
+ // Verify reset completed
84
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(3);
85
+ expect(updatedDoc.state.global.documentTypes.find((dt) => dt.id === "old-type-1")).toBeUndefined();
86
+ expect(updatedDoc.state.global.documentTypes.find((dt) => dt.id === "new-type-1")).toBeDefined();
87
+ });
88
+ it("should maintain state integrity with complex add/remove sequences", () => {
89
+ const document = utils.createDocument();
90
+ // Add multiple types
91
+ let updatedDoc = reducer(document, creators.addDocumentType({ id: "type-a", documentType: "a" }));
92
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({ id: "type-b", documentType: "b" }));
93
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({ id: "type-c", documentType: "c" }));
94
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(3);
95
+ // Remove middle one
96
+ updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "type-b" }));
97
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(2);
98
+ // Add it back with new documentType
99
+ updatedDoc = reducer(updatedDoc, creators.addDocumentType({ id: "type-b", documentType: "b-new" }));
100
+ expect(updatedDoc.state.global.documentTypes).toHaveLength(3);
101
+ // Verify order and content
102
+ const typeB = updatedDoc.state.global.documentTypes.find((dt) => dt.id === "type-b");
103
+ expect(typeB?.documentType).toBe("b-new");
104
+ });
17
105
  });
18
106
  });
@@ -1 +1 @@
1
- {"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../document-models/subgraph-module/src/reducers/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,yCAAyC,CAAC;AAEtG,eAAO,MAAM,OAAO,EAAE,sCAOrB,CAAC"}
1
+ {"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../document-models/subgraph-module/src/reducers/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,yCAAyC,CAAC;AAEtG,eAAO,MAAM,OAAO,EAAE,sCAWrB,CAAC"}
@@ -1,6 +1,10 @@
1
1
  export const reducer = {
2
2
  setSubgraphNameOperation(state, action, dispatch) {
3
- state.name = action.input.name;
3
+ const trimmedName = action.input.name.trim();
4
+ if (trimmedName === "") {
5
+ throw new Error("Subgraph name cannot be empty");
6
+ }
7
+ state.name = trimmedName;
4
8
  },
5
9
  setSubgraphStatusOperation(state, action, dispatch) {
6
10
  state.status = action.input.status;
@@ -2,23 +2,44 @@
2
2
  * This is a scaffold file meant for customization:
3
3
  * - change it by adding new tests or modifying the existing ones
4
4
  */
5
- import { describe, it, expect, beforeEach } from "vitest";
6
- import { generateMock } from "@powerhousedao/codegen";
7
- import utils from "../../gen/utils.js";
8
- import { z } from "../../gen/schema/index.js";
9
- import { reducer } from "../../gen/reducer.js";
5
+ import { beforeEach, describe, expect, it } from "vitest";
10
6
  import * as creators from "../../gen/base-operations/creators.js";
7
+ import { reducer } from "../../gen/reducer.js";
8
+ import utils from "../../gen/utils.js";
11
9
  describe("BaseOperations Operations", () => {
12
10
  let document;
13
11
  beforeEach(() => {
14
12
  document = utils.createDocument();
15
13
  });
16
- it("should handle setSubgraphName operation", () => {
17
- const input = generateMock(z.SetSubgraphNameInputSchema());
18
- const updatedDocument = reducer(document, creators.setSubgraphName(input));
19
- expect(updatedDocument.operations.global).toHaveLength(1);
20
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_SUBGRAPH_NAME");
21
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
22
- expect(updatedDocument.operations.global[0].index).toEqual(0);
14
+ describe("setSubgraphName", () => {
15
+ it("should mutate state with new name", () => {
16
+ const input = { name: "My Subgraph" };
17
+ const updatedDocument = reducer(document, creators.setSubgraphName(input));
18
+ expect(updatedDocument.state.global.name).toBe("My Subgraph");
19
+ });
20
+ it("should reject empty string and store error in operation", () => {
21
+ const input = { name: "" };
22
+ const updatedDocument = reducer(document, creators.setSubgraphName(input));
23
+ expect(updatedDocument.operations.global).toHaveLength(1);
24
+ expect(updatedDocument.operations.global[0].error).toBe("Subgraph name cannot be empty");
25
+ expect(updatedDocument.state.global.name).toBe("");
26
+ });
27
+ });
28
+ describe("setSubgraphStatus", () => {
29
+ it("should mutate state with new status", () => {
30
+ const input = { status: "CONFIRMED" };
31
+ const updatedDocument = reducer(document, creators.setSubgraphStatus(input));
32
+ expect(updatedDocument.state.global.status).toBe("CONFIRMED");
33
+ });
34
+ it("should transition from DRAFT to CONFIRMED", () => {
35
+ expect(document.state.global.status).toBe("DRAFT");
36
+ const updatedDocument = reducer(document, creators.setSubgraphStatus({ status: "CONFIRMED" }));
37
+ expect(updatedDocument.state.global.status).toBe("CONFIRMED");
38
+ });
39
+ it("should transition from CONFIRMED to DRAFT", () => {
40
+ const confirmedDoc = reducer(document, creators.setSubgraphStatus({ status: "CONFIRMED" }));
41
+ const updatedDocument = reducer(confirmedDoc, creators.setSubgraphStatus({ status: "DRAFT" }));
42
+ expect(updatedDocument.state.global.status).toBe("DRAFT");
43
+ });
23
44
  });
24
45
  });
@@ -2,17 +2,34 @@
2
2
  * This is a scaffold file meant for customization:
3
3
  * - change it by adding new tests or modifying the existing ones
4
4
  */
5
- import { describe, it, expect, beforeEach } from "vitest";
6
- import utils, { initialGlobalState, initialLocalState, } from "../../gen/utils.js";
5
+ import { describe, expect, it } from "vitest";
6
+ import * as creators from "../../gen/base-operations/creators.js";
7
+ import { reducer } from "../../gen/reducer.js";
8
+ import utils from "../../gen/utils.js";
7
9
  describe("Subgraph Module Document Model", () => {
8
- it("should create a new Subgraph Module document", () => {
10
+ it("should have correct initial values", () => {
9
11
  const document = utils.createDocument();
10
- expect(document).toBeDefined();
11
- expect(document.header.documentType).toBe("powerhouse/subgraph");
12
+ expect(document.state.global.name).toBe("");
13
+ expect(document.state.global.status).toBe("DRAFT");
12
14
  });
13
- it("should create a new Subgraph Module document with a valid initial state", () => {
15
+ it("should handle multiple operations and maintain consistency", () => {
14
16
  const document = utils.createDocument();
15
- expect(document.state.global).toStrictEqual(initialGlobalState);
16
- expect(document.state.local).toStrictEqual(initialLocalState);
17
+ let updatedDoc = reducer(document, creators.setSubgraphName({ name: "Test Subgraph" }));
18
+ updatedDoc = reducer(updatedDoc, creators.setSubgraphStatus({ status: "CONFIRMED" }));
19
+ // Verify state consistency
20
+ expect(updatedDoc.state.global.name).toBe("Test Subgraph");
21
+ expect(updatedDoc.state.global.status).toBe("CONFIRMED");
22
+ });
23
+ it("should handle complete workflow: set name and confirm status", () => {
24
+ const document = utils.createDocument();
25
+ // Step 1: Set subgraph name
26
+ let updatedDoc = reducer(document, creators.setSubgraphName({ name: "Production Subgraph" }));
27
+ expect(updatedDoc.state.global.name).toBe("Production Subgraph");
28
+ // Step 2: Confirm subgraph status
29
+ updatedDoc = reducer(updatedDoc, creators.setSubgraphStatus({ status: "CONFIRMED" }));
30
+ expect(updatedDoc.state.global.status).toBe("CONFIRMED");
31
+ // Verify final state
32
+ expect(updatedDoc.state.global.name).toBe("Production Subgraph");
33
+ expect(updatedDoc.state.global.status).toBe("CONFIRMED");
17
34
  });
18
35
  });
@@ -1 +1 @@
1
- {"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../document-models/vetra-package/src/reducers/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oCAAoC,EAAE,MAAM,yCAAyC,CAAC;AAEpG,eAAO,MAAM,OAAO,EAAE,oCAoCrB,CAAC"}
1
+ {"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../document-models/vetra-package/src/reducers/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oCAAoC,EAAE,MAAM,yCAAyC,CAAC;AAEpG,eAAO,MAAM,OAAO,EAAE,oCA4CrB,CAAC"}
@@ -21,6 +21,11 @@ export const reducer = {
21
21
  state.author.website = action.input.website;
22
22
  },
23
23
  addPackageKeywordOperation(state, action, dispatch) {
24
+ // Check for duplicate ID
25
+ const existingId = state.keywords.find((keyword) => keyword.id === action.input.id);
26
+ if (existingId) {
27
+ throw new Error(`Keyword with id "${action.input.id}" already exists`);
28
+ }
24
29
  state.keywords.push(action.input);
25
30
  },
26
31
  removePackageKeywordOperation(state, action, dispatch) {