@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.
- package/dist/document-models/app-module/src/reducers/base-operations.d.ts.map +1 -1
- package/dist/document-models/app-module/src/reducers/base-operations.js +5 -1
- package/dist/document-models/app-module/src/tests/base-operations.test.js +157 -30
- package/dist/document-models/app-module/src/tests/dnd-operations.test.js +38 -7
- package/dist/document-models/app-module/src/tests/document-model.test.js +80 -8
- package/dist/document-models/document-editor/src/reducers/base-operations.d.ts.map +1 -1
- package/dist/document-models/document-editor/src/reducers/base-operations.js +10 -1
- package/dist/document-models/document-editor/src/tests/base-operations.test.js +137 -23
- package/dist/document-models/document-editor/src/tests/document-model.test.js +91 -8
- package/dist/document-models/processor-module/src/reducers/base-operations.d.ts.map +1 -1
- package/dist/document-models/processor-module/src/reducers/base-operations.js +15 -2
- package/dist/document-models/processor-module/src/tests/base-operations.test.js +153 -33
- package/dist/document-models/processor-module/src/tests/document-model.test.js +96 -8
- package/dist/document-models/subgraph-module/src/reducers/base-operations.d.ts.map +1 -1
- package/dist/document-models/subgraph-module/src/reducers/base-operations.js +5 -1
- package/dist/document-models/subgraph-module/src/tests/base-operations.test.js +33 -12
- package/dist/document-models/subgraph-module/src/tests/document-model.test.js +25 -8
- package/dist/document-models/vetra-package/src/reducers/base-operations.d.ts.map +1 -1
- package/dist/document-models/vetra-package/src/reducers/base-operations.js +5 -0
- package/dist/document-models/vetra-package/src/tests/base-operations.test.js +171 -75
- package/dist/document-models/vetra-package/src/tests/document-model.test.js +101 -8
- package/dist/editors/app-editor/components/AppEditorForm.d.ts.map +1 -1
- package/dist/editors/app-editor/components/AppEditorForm.js +2 -2
- package/dist/editors/app-editor/editor.test.d.ts +2 -0
- package/dist/editors/app-editor/editor.test.d.ts.map +1 -0
- package/dist/editors/app-editor/editor.test.js +422 -0
- package/dist/editors/document-editor/components/DocumentEditorForm.d.ts.map +1 -1
- package/dist/editors/document-editor/components/DocumentEditorForm.js +1 -1
- package/dist/editors/document-editor/editor.test.d.ts +2 -0
- package/dist/editors/document-editor/editor.test.d.ts.map +1 -0
- package/dist/editors/document-editor/editor.test.js +374 -0
- package/dist/editors/processor-editor/components/ProcessorEditorForm.d.ts.map +1 -1
- package/dist/editors/processor-editor/components/ProcessorEditorForm.js +1 -1
- package/dist/editors/processor-editor/editor.test.d.ts +2 -0
- package/dist/editors/processor-editor/editor.test.d.ts.map +1 -0
- package/dist/editors/processor-editor/editor.test.js +459 -0
- package/dist/editors/subgraph-editor/components/SubgraphEditorForm.d.ts.map +1 -1
- package/dist/editors/subgraph-editor/components/SubgraphEditorForm.js +3 -3
- package/dist/editors/subgraph-editor/editor.test.d.ts +2 -0
- package/dist/editors/subgraph-editor/editor.test.d.ts.map +1 -0
- package/dist/editors/subgraph-editor/editor.test.js +201 -0
- package/dist/editors/vetra-package/components/MetaForm.d.ts.map +1 -1
- package/dist/editors/vetra-package/components/MetaForm.js +3 -3
- package/dist/editors/vetra-package/editor.test.d.ts +2 -0
- package/dist/editors/vetra-package/editor.test.d.ts.map +1 -0
- package/dist/editors/vetra-package/editor.test.js +330 -0
- package/dist/processors/codegen/__tests__/codegen-processor-e2e.test.d.ts +2 -0
- package/dist/processors/codegen/__tests__/codegen-processor-e2e.test.d.ts.map +1 -0
- package/dist/processors/codegen/__tests__/codegen-processor-e2e.test.js +615 -0
- package/dist/processors/codegen/__tests__/factory.test.d.ts +2 -0
- package/dist/processors/codegen/__tests__/factory.test.d.ts.map +1 -0
- package/dist/processors/codegen/__tests__/factory.test.js +190 -0
- package/dist/setupTests.d.ts +2 -0
- package/dist/setupTests.d.ts.map +1 -0
- package/dist/setupTests.js +1 -0
- package/dist/style.css +9 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/vitest.config.d.ts.map +1 -1
- package/dist/vitest.config.js +9 -0
- package/package.json +19 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../document-models/app-module/src/reducers/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,yCAAyC,CAAC;AAEjG,eAAO,MAAM,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../document-models/app-module/src/reducers/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,yCAAyC,CAAC;AAEjG,eAAO,MAAM,OAAO,EAAE,iCA+BrB,CAAC"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export const reducer = {
|
|
2
2
|
setAppNameOperation(state, action, dispatch) {
|
|
3
|
-
|
|
3
|
+
const trimmedName = action.input.name.trim();
|
|
4
|
+
if (trimmedName === "") {
|
|
5
|
+
throw new Error("App name cannot be empty");
|
|
6
|
+
}
|
|
7
|
+
state.name = trimmedName;
|
|
4
8
|
},
|
|
5
9
|
setAppStatusOperation(state, action, dispatch) {
|
|
6
10
|
state.status = action.input.status;
|
|
@@ -2,47 +2,174 @@
|
|
|
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 { generateMock } from "@powerhousedao/codegen";
|
|
6
5
|
import { beforeEach, describe, expect, it } from "vitest";
|
|
7
6
|
import * as creators from "../../gen/base-operations/creators.js";
|
|
8
7
|
import { reducer } from "../../gen/reducer.js";
|
|
9
|
-
import { z } from "../../gen/schema/index.js";
|
|
10
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
describe("setAppName", () => {
|
|
15
|
+
it("should mutate state with new name", () => {
|
|
16
|
+
const input = { name: "My Test App" };
|
|
17
|
+
const updatedDocument = reducer(document, creators.setAppName(input));
|
|
18
|
+
expect(updatedDocument.state.global.name).toBe("My Test App");
|
|
19
|
+
});
|
|
20
|
+
it("should reject empty string and store error in operation", () => {
|
|
21
|
+
const input = { name: "" };
|
|
22
|
+
const updatedDocument = reducer(document, creators.setAppName(input));
|
|
23
|
+
// The operation should be recorded but with an error
|
|
24
|
+
expect(updatedDocument.operations.global).toHaveLength(1);
|
|
25
|
+
expect(updatedDocument.operations.global[0].error).toBe("App name cannot be empty");
|
|
26
|
+
// State should remain unchanged
|
|
27
|
+
expect(updatedDocument.state.global.name).toBe("");
|
|
28
|
+
});
|
|
29
|
+
it("should reject whitespace-only name and store error in operation", () => {
|
|
30
|
+
const input = { name: " " };
|
|
31
|
+
const updatedDocument = reducer(document, creators.setAppName(input));
|
|
32
|
+
// The operation should be recorded but with an error
|
|
33
|
+
expect(updatedDocument.operations.global).toHaveLength(1);
|
|
34
|
+
expect(updatedDocument.operations.global[0].error).toBe("App name cannot be empty");
|
|
35
|
+
// State should remain unchanged
|
|
36
|
+
expect(updatedDocument.state.global.name).toBe("");
|
|
37
|
+
});
|
|
23
38
|
});
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
describe("setAppStatus", () => {
|
|
40
|
+
it("should mutate state with new status", () => {
|
|
41
|
+
const input = { status: "CONFIRMED" };
|
|
42
|
+
const updatedDocument = reducer(document, creators.setAppStatus(input));
|
|
43
|
+
expect(updatedDocument.state.global.status).toBe("CONFIRMED");
|
|
44
|
+
});
|
|
45
|
+
it("should transition from DRAFT to CONFIRMED", () => {
|
|
46
|
+
expect(document.state.global.status).toBe("DRAFT");
|
|
47
|
+
const updatedDocument = reducer(document, creators.setAppStatus({ status: "CONFIRMED" }));
|
|
48
|
+
expect(updatedDocument.state.global.status).toBe("CONFIRMED");
|
|
49
|
+
});
|
|
50
|
+
it("should transition from CONFIRMED to DRAFT", () => {
|
|
51
|
+
const confirmedDoc = reducer(document, creators.setAppStatus({ status: "CONFIRMED" }));
|
|
52
|
+
const updatedDocument = reducer(confirmedDoc, creators.setAppStatus({ status: "DRAFT" }));
|
|
53
|
+
expect(updatedDocument.state.global.status).toBe("DRAFT");
|
|
54
|
+
});
|
|
55
|
+
it("should handle setting same status twice", () => {
|
|
56
|
+
const firstUpdate = reducer(document, creators.setAppStatus({ status: "CONFIRMED" }));
|
|
57
|
+
const secondUpdate = reducer(firstUpdate, creators.setAppStatus({ status: "CONFIRMED" }));
|
|
58
|
+
expect(secondUpdate.state.global.status).toBe("CONFIRMED");
|
|
59
|
+
expect(secondUpdate.operations.global).toHaveLength(2);
|
|
60
|
+
});
|
|
31
61
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
62
|
+
describe("addDocumentType", () => {
|
|
63
|
+
it("should mutate state by adding document type to array", () => {
|
|
64
|
+
const input = {
|
|
65
|
+
documentType: "powerhouse/test",
|
|
66
|
+
};
|
|
67
|
+
const updatedDocument = reducer(document, creators.addDocumentType(input));
|
|
68
|
+
expect(updatedDocument.state.global.allowedDocumentTypes).toContain("powerhouse/test");
|
|
69
|
+
});
|
|
70
|
+
it("should initialize array when allowedDocumentTypes is null", () => {
|
|
71
|
+
// Initial state has allowedDocumentTypes as null
|
|
72
|
+
expect(document.state.global.allowedDocumentTypes).toBeNull();
|
|
73
|
+
const input = {
|
|
74
|
+
documentType: "powerhouse/first",
|
|
75
|
+
};
|
|
76
|
+
const updatedDocument = reducer(document, creators.addDocumentType(input));
|
|
77
|
+
expect(updatedDocument.state.global.allowedDocumentTypes).toEqual([
|
|
78
|
+
"powerhouse/first",
|
|
79
|
+
]);
|
|
80
|
+
});
|
|
81
|
+
it("should add multiple document types sequentially", () => {
|
|
82
|
+
let updatedDoc = reducer(document, creators.addDocumentType({
|
|
83
|
+
documentType: "powerhouse/a",
|
|
84
|
+
}));
|
|
85
|
+
updatedDoc = reducer(updatedDoc, creators.addDocumentType({
|
|
86
|
+
documentType: "powerhouse/b",
|
|
87
|
+
}));
|
|
88
|
+
updatedDoc = reducer(updatedDoc, creators.addDocumentType({
|
|
89
|
+
documentType: "powerhouse/c",
|
|
90
|
+
}));
|
|
91
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toHaveLength(3);
|
|
92
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toContain("powerhouse/a");
|
|
93
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toContain("powerhouse/b");
|
|
94
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toContain("powerhouse/c");
|
|
95
|
+
});
|
|
96
|
+
it("should reject duplicate document types", () => {
|
|
97
|
+
const input = {
|
|
98
|
+
documentType: "powerhouse/duplicate",
|
|
99
|
+
};
|
|
100
|
+
// First addition should succeed
|
|
101
|
+
let updatedDoc = reducer(document, creators.addDocumentType(input));
|
|
102
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toHaveLength(1);
|
|
103
|
+
// Second addition with same documentType should not add duplicate (uses Set)
|
|
104
|
+
updatedDoc = reducer(updatedDoc, creators.addDocumentType({
|
|
105
|
+
documentType: "powerhouse/duplicate",
|
|
106
|
+
}));
|
|
107
|
+
// Should still only have 1 item (no duplicates in a Set)
|
|
108
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toHaveLength(1);
|
|
109
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toContain("powerhouse/duplicate");
|
|
110
|
+
});
|
|
111
|
+
it("should handle adding various documentType values", () => {
|
|
112
|
+
let updatedDoc = reducer(document, creators.addDocumentType({ documentType: "powerhouse/budget" }));
|
|
113
|
+
updatedDoc = reducer(updatedDoc, creators.addDocumentType({ documentType: "powerhouse/document-model" }));
|
|
114
|
+
updatedDoc = reducer(updatedDoc, creators.addDocumentType({ documentType: "custom/type" }));
|
|
115
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toContain("powerhouse/budget");
|
|
116
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toContain("powerhouse/document-model");
|
|
117
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toContain("custom/type");
|
|
118
|
+
});
|
|
39
119
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
120
|
+
describe("removeDocumentType", () => {
|
|
121
|
+
it("should mutate state by removing document type from array", () => {
|
|
122
|
+
// First add a document type
|
|
123
|
+
let updatedDoc = reducer(document, creators.addDocumentType({
|
|
124
|
+
documentType: "powerhouse/to-remove",
|
|
125
|
+
}));
|
|
126
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toContain("powerhouse/to-remove");
|
|
127
|
+
// Then remove it
|
|
128
|
+
updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ documentType: "powerhouse/to-remove" }));
|
|
129
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).not.toContain("powerhouse/to-remove");
|
|
130
|
+
});
|
|
131
|
+
it("should remove existing document type", () => {
|
|
132
|
+
let updatedDoc = reducer(document, creators.addDocumentType({
|
|
133
|
+
documentType: "powerhouse/existing",
|
|
134
|
+
}));
|
|
135
|
+
const lengthBefore = updatedDoc.state.global.allowedDocumentTypes?.length ?? 0;
|
|
136
|
+
updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ documentType: "powerhouse/existing" }));
|
|
137
|
+
expect(updatedDoc.state.global.allowedDocumentTypes?.length).toBe(lengthBefore - 1);
|
|
138
|
+
expect(updatedDoc.state.global.allowedDocumentTypes?.includes("powerhouse/existing")).toBe(false);
|
|
139
|
+
});
|
|
140
|
+
it("should gracefully handle non-existent document type", () => {
|
|
141
|
+
const updatedDocument = reducer(document, creators.removeDocumentType({ documentType: "non-existent-type" }));
|
|
142
|
+
// Should result in empty array
|
|
143
|
+
expect(updatedDocument.state.global.allowedDocumentTypes).toEqual([]);
|
|
144
|
+
});
|
|
145
|
+
it("should handle null array gracefully", () => {
|
|
146
|
+
expect(document.state.global.allowedDocumentTypes).toBeNull();
|
|
147
|
+
const updatedDocument = reducer(document, creators.removeDocumentType({ documentType: "any-type" }));
|
|
148
|
+
expect(updatedDocument.state.global.allowedDocumentTypes).toEqual([]);
|
|
149
|
+
});
|
|
150
|
+
it("should add then immediately remove item", () => {
|
|
151
|
+
let updatedDoc = reducer(document, creators.addDocumentType({
|
|
152
|
+
documentType: "powerhouse/temp",
|
|
153
|
+
}));
|
|
154
|
+
updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ documentType: "powerhouse/temp" }));
|
|
155
|
+
expect(updatedDoc.state.global.allowedDocumentTypes?.includes("powerhouse/temp")).toBe(false);
|
|
156
|
+
expect(updatedDoc.operations.global).toHaveLength(2);
|
|
157
|
+
});
|
|
158
|
+
it("should remove from list and preserve other items", () => {
|
|
159
|
+
let updatedDoc = reducer(document, creators.addDocumentType({
|
|
160
|
+
documentType: "powerhouse/a",
|
|
161
|
+
}));
|
|
162
|
+
updatedDoc = reducer(updatedDoc, creators.addDocumentType({
|
|
163
|
+
documentType: "powerhouse/b",
|
|
164
|
+
}));
|
|
165
|
+
updatedDoc = reducer(updatedDoc, creators.addDocumentType({
|
|
166
|
+
documentType: "powerhouse/c",
|
|
167
|
+
}));
|
|
168
|
+
updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ documentType: "powerhouse/b" }));
|
|
169
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toHaveLength(2);
|
|
170
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toContain("powerhouse/a");
|
|
171
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toContain("powerhouse/c");
|
|
172
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).not.toContain("powerhouse/b");
|
|
173
|
+
});
|
|
47
174
|
});
|
|
48
175
|
});
|
|
@@ -13,12 +13,43 @@ describe("DndOperations Operations", () => {
|
|
|
13
13
|
beforeEach(() => {
|
|
14
14
|
document = utils.createDocument();
|
|
15
15
|
});
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
describe("setDragAndDropEnabled", () => {
|
|
17
|
+
it("should handle setDragAndDropEnabled operation", () => {
|
|
18
|
+
const input = generateMock(z.SetDragAndDropEnabledInputSchema());
|
|
19
|
+
const updatedDocument = reducer(document, creators.setDragAndDropEnabled(input));
|
|
20
|
+
expect(updatedDocument.operations.global).toHaveLength(1);
|
|
21
|
+
expect(updatedDocument.operations.global[0].action.type).toBe("SET_DRAG_AND_DROP_ENABLED");
|
|
22
|
+
expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
|
|
23
|
+
expect(updatedDocument.operations.global[0].index).toEqual(0);
|
|
24
|
+
});
|
|
25
|
+
it("should mutate state with new enabled value", () => {
|
|
26
|
+
const input = { enabled: false };
|
|
27
|
+
const updatedDocument = reducer(document, creators.setDragAndDropEnabled(input));
|
|
28
|
+
expect(updatedDocument.state.global.isDragAndDropEnabled).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
it("should enable drag and drop from initial state", () => {
|
|
31
|
+
// Initial state has isDragAndDropEnabled = true
|
|
32
|
+
expect(document.state.global.isDragAndDropEnabled).toBe(true);
|
|
33
|
+
const updatedDocument = reducer(document, creators.setDragAndDropEnabled({ enabled: true }));
|
|
34
|
+
expect(updatedDocument.state.global.isDragAndDropEnabled).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
it("should disable drag and drop", () => {
|
|
37
|
+
const updatedDocument = reducer(document, creators.setDragAndDropEnabled({ enabled: false }));
|
|
38
|
+
expect(updatedDocument.state.global.isDragAndDropEnabled).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
it("should toggle drag and drop in sequence", () => {
|
|
41
|
+
let updatedDoc = reducer(document, creators.setDragAndDropEnabled({ enabled: false }));
|
|
42
|
+
expect(updatedDoc.state.global.isDragAndDropEnabled).toBe(false);
|
|
43
|
+
updatedDoc = reducer(updatedDoc, creators.setDragAndDropEnabled({ enabled: true }));
|
|
44
|
+
expect(updatedDoc.state.global.isDragAndDropEnabled).toBe(true);
|
|
45
|
+
updatedDoc = reducer(updatedDoc, creators.setDragAndDropEnabled({ enabled: false }));
|
|
46
|
+
expect(updatedDoc.state.global.isDragAndDropEnabled).toBe(false);
|
|
47
|
+
expect(updatedDoc.operations.global).toHaveLength(3);
|
|
48
|
+
});
|
|
49
|
+
it("should update boolean field directly", () => {
|
|
50
|
+
const updatedDocument = reducer(document, creators.setDragAndDropEnabled({ enabled: false }));
|
|
51
|
+
expect(updatedDocument.state.global.isDragAndDropEnabled).toBeDefined();
|
|
52
|
+
expect(typeof updatedDocument.state.global.isDragAndDropEnabled).toBe("boolean");
|
|
53
|
+
});
|
|
23
54
|
});
|
|
24
55
|
});
|
|
@@ -2,17 +2,89 @@
|
|
|
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,
|
|
6
|
-
import
|
|
5
|
+
import { describe, expect, it } from "vitest";
|
|
6
|
+
import * as baseCreators from "../../gen/base-operations/creators.js";
|
|
7
|
+
import * as dndCreators from "../../gen/dnd-operations/creators.js";
|
|
8
|
+
import { reducer } from "../../gen/reducer.js";
|
|
9
|
+
import utils from "../../gen/utils.js";
|
|
7
10
|
describe("App Module Document Model", () => {
|
|
8
|
-
it("should
|
|
11
|
+
it("should have correct initial values", () => {
|
|
9
12
|
const document = utils.createDocument();
|
|
10
|
-
expect(document).
|
|
11
|
-
expect(document.
|
|
13
|
+
expect(document.state.global.name).toBe("");
|
|
14
|
+
expect(document.state.global.status).toBe("DRAFT");
|
|
15
|
+
expect(document.state.global.allowedDocumentTypes).toBeNull();
|
|
16
|
+
expect(document.state.global.isDragAndDropEnabled).toBe(true);
|
|
12
17
|
});
|
|
13
|
-
it("should
|
|
18
|
+
it("should handle multiple operations and maintain consistency", () => {
|
|
14
19
|
const document = utils.createDocument();
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
let updatedDoc = reducer(document, baseCreators.setAppName({ name: "Test App" }));
|
|
21
|
+
updatedDoc = reducer(updatedDoc, baseCreators.setAppStatus({ status: "CONFIRMED" }));
|
|
22
|
+
updatedDoc = reducer(updatedDoc, baseCreators.addDocumentType({
|
|
23
|
+
documentType: "powerhouse/test",
|
|
24
|
+
}));
|
|
25
|
+
// Verify state consistency
|
|
26
|
+
expect(updatedDoc.state.global.name).toBe("Test App");
|
|
27
|
+
expect(updatedDoc.state.global.status).toBe("CONFIRMED");
|
|
28
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toHaveLength(1);
|
|
29
|
+
});
|
|
30
|
+
describe("Complex Scenarios", () => {
|
|
31
|
+
it("should handle locked configuration: disable DnD and clear document types", () => {
|
|
32
|
+
const document = utils.createDocument();
|
|
33
|
+
// Add some document types first
|
|
34
|
+
let updatedDoc = reducer(document, baseCreators.addDocumentType({ documentType: "powerhouse/type1" }));
|
|
35
|
+
updatedDoc = reducer(updatedDoc, baseCreators.addDocumentType({ documentType: "powerhouse/type2" }));
|
|
36
|
+
// Disable drag and drop
|
|
37
|
+
updatedDoc = reducer(updatedDoc, dndCreators.setDragAndDropEnabled({ enabled: false }));
|
|
38
|
+
expect(updatedDoc.state.global.isDragAndDropEnabled).toBe(false);
|
|
39
|
+
// Remove all document types
|
|
40
|
+
updatedDoc = reducer(updatedDoc, baseCreators.removeDocumentType({ documentType: "powerhouse/type1" }));
|
|
41
|
+
updatedDoc = reducer(updatedDoc, baseCreators.removeDocumentType({ documentType: "powerhouse/type2" }));
|
|
42
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toEqual([]);
|
|
43
|
+
// Set as confirmed to "lock" it
|
|
44
|
+
updatedDoc = reducer(updatedDoc, baseCreators.setAppStatus({ status: "CONFIRMED" }));
|
|
45
|
+
// Verify locked configuration
|
|
46
|
+
expect(updatedDoc.state.global.isDragAndDropEnabled).toBe(false);
|
|
47
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toHaveLength(0);
|
|
48
|
+
expect(updatedDoc.state.global.status).toBe("CONFIRMED");
|
|
49
|
+
});
|
|
50
|
+
it("should handle reset scenario: add new document types from scratch", () => {
|
|
51
|
+
const document = utils.createDocument();
|
|
52
|
+
// Start with null allowedDocumentTypes
|
|
53
|
+
expect(document.state.global.allowedDocumentTypes).toBeNull();
|
|
54
|
+
// Add new types from scratch
|
|
55
|
+
let updatedDoc = reducer(document, baseCreators.addDocumentType({
|
|
56
|
+
documentType: "powerhouse/new1",
|
|
57
|
+
}));
|
|
58
|
+
updatedDoc = reducer(updatedDoc, baseCreators.addDocumentType({
|
|
59
|
+
documentType: "powerhouse/new2",
|
|
60
|
+
}));
|
|
61
|
+
updatedDoc = reducer(updatedDoc, baseCreators.addDocumentType({
|
|
62
|
+
documentType: "powerhouse/new3",
|
|
63
|
+
}));
|
|
64
|
+
// Verify reset completed
|
|
65
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toHaveLength(3);
|
|
66
|
+
expect(updatedDoc.state.global.allowedDocumentTypes?.includes("powerhouse/new1")).toBe(true);
|
|
67
|
+
expect(updatedDoc.state.global.allowedDocumentTypes?.includes("powerhouse/new2")).toBe(true);
|
|
68
|
+
expect(updatedDoc.state.global.allowedDocumentTypes?.includes("powerhouse/new3")).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
it("should maintain state integrity with complex add/remove sequences", () => {
|
|
71
|
+
const document = utils.createDocument();
|
|
72
|
+
// Add multiple types
|
|
73
|
+
let updatedDoc = reducer(document, baseCreators.addDocumentType({ documentType: "type-a" }));
|
|
74
|
+
updatedDoc = reducer(updatedDoc, baseCreators.addDocumentType({ documentType: "type-b" }));
|
|
75
|
+
updatedDoc = reducer(updatedDoc, baseCreators.addDocumentType({ documentType: "type-c" }));
|
|
76
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toHaveLength(3);
|
|
77
|
+
// Remove middle one
|
|
78
|
+
updatedDoc = reducer(updatedDoc, baseCreators.removeDocumentType({ documentType: "type-b" }));
|
|
79
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toHaveLength(2);
|
|
80
|
+
// Add it back with different name
|
|
81
|
+
updatedDoc = reducer(updatedDoc, baseCreators.addDocumentType({ documentType: "type-b-new" }));
|
|
82
|
+
expect(updatedDoc.state.global.allowedDocumentTypes).toHaveLength(3);
|
|
83
|
+
// Verify content
|
|
84
|
+
expect(updatedDoc.state.global.allowedDocumentTypes?.includes("type-a")).toBe(true);
|
|
85
|
+
expect(updatedDoc.state.global.allowedDocumentTypes?.includes("type-c")).toBe(true);
|
|
86
|
+
expect(updatedDoc.state.global.allowedDocumentTypes?.includes("type-b-new")).toBe(true);
|
|
87
|
+
expect(updatedDoc.state.global.allowedDocumentTypes?.includes("type-b")).toBe(false);
|
|
88
|
+
});
|
|
17
89
|
});
|
|
18
90
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../document-models/document-editor/src/reducers/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,yCAAyC,CAAC;AAEtG,eAAO,MAAM,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../../../document-models/document-editor/src/reducers/base-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,yCAAyC,CAAC;AAEtG,eAAO,MAAM,OAAO,EAAE,sCAgCrB,CAAC"}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
export const reducer = {
|
|
2
2
|
setEditorNameOperation(state, action, dispatch) {
|
|
3
|
-
|
|
3
|
+
const trimmedName = action.input.name.trim();
|
|
4
|
+
if (trimmedName === "") {
|
|
5
|
+
throw new Error("Editor name cannot be empty");
|
|
6
|
+
}
|
|
7
|
+
state.name = trimmedName;
|
|
4
8
|
},
|
|
5
9
|
addDocumentTypeOperation(state, action, dispatch) {
|
|
10
|
+
// Check for duplicate ID
|
|
11
|
+
const existingId = state.documentTypes.find((dt) => dt.id === action.input.id);
|
|
12
|
+
if (existingId) {
|
|
13
|
+
throw new Error(`Document type with id "${action.input.id}" already exists`);
|
|
14
|
+
}
|
|
6
15
|
state.documentTypes.push({
|
|
7
16
|
id: action.input.id,
|
|
8
17
|
documentType: action.input.documentType,
|
|
@@ -2,39 +2,153 @@
|
|
|
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 { generateMock } from "@powerhousedao/codegen";
|
|
6
5
|
import { beforeEach, describe, expect, it } from "vitest";
|
|
7
6
|
import * as creators from "../../gen/base-operations/creators.js";
|
|
8
7
|
import { reducer } from "../../gen/reducer.js";
|
|
9
|
-
import { z } from "../../gen/schema/index.js";
|
|
10
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
describe("setEditorName", () => {
|
|
15
|
+
it("should mutate state with new name", () => {
|
|
16
|
+
const input = { name: "My Editor" };
|
|
17
|
+
const updatedDocument = reducer(document, creators.setEditorName(input));
|
|
18
|
+
expect(updatedDocument.state.global.name).toBe("My Editor");
|
|
19
|
+
});
|
|
20
|
+
it("should reject empty string and store error in operation", () => {
|
|
21
|
+
const input = { name: "" };
|
|
22
|
+
const updatedDocument = reducer(document, creators.setEditorName(input));
|
|
23
|
+
expect(updatedDocument.operations.global).toHaveLength(1);
|
|
24
|
+
expect(updatedDocument.operations.global[0].error).toBe("Editor name cannot be empty");
|
|
25
|
+
expect(updatedDocument.state.global.name).toBe("");
|
|
26
|
+
});
|
|
23
27
|
});
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
describe("setEditorStatus", () => {
|
|
29
|
+
it("should mutate state with new status", () => {
|
|
30
|
+
const input = { status: "CONFIRMED" };
|
|
31
|
+
const updatedDocument = reducer(document, creators.setEditorStatus(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.setEditorStatus({ 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.setEditorStatus({ status: "CONFIRMED" }));
|
|
41
|
+
const updatedDocument = reducer(confirmedDoc, creators.setEditorStatus({ status: "DRAFT" }));
|
|
42
|
+
expect(updatedDocument.state.global.status).toBe("DRAFT");
|
|
43
|
+
});
|
|
31
44
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
45
|
+
describe("addDocumentType", () => {
|
|
46
|
+
it("should mutate state by adding document type to array", () => {
|
|
47
|
+
const input = {
|
|
48
|
+
id: "test-type-1",
|
|
49
|
+
documentType: "powerhouse/test",
|
|
50
|
+
};
|
|
51
|
+
const updatedDocument = reducer(document, creators.addDocumentType(input));
|
|
52
|
+
expect(updatedDocument.state.global.documentTypes).toContainEqual({
|
|
53
|
+
id: "test-type-1",
|
|
54
|
+
documentType: "powerhouse/test",
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
it("should add to empty array from initial state", () => {
|
|
58
|
+
expect(document.state.global.documentTypes).toEqual([]);
|
|
59
|
+
const input = {
|
|
60
|
+
id: "first-type",
|
|
61
|
+
documentType: "powerhouse/first",
|
|
62
|
+
};
|
|
63
|
+
const updatedDocument = reducer(document, creators.addDocumentType(input));
|
|
64
|
+
expect(updatedDocument.state.global.documentTypes).toEqual([
|
|
65
|
+
{ id: "first-type", documentType: "powerhouse/first" },
|
|
66
|
+
]);
|
|
67
|
+
});
|
|
68
|
+
it("should add multiple document types sequentially", () => {
|
|
69
|
+
let updatedDoc = reducer(document, creators.addDocumentType({
|
|
70
|
+
id: "type-1",
|
|
71
|
+
documentType: "powerhouse/a",
|
|
72
|
+
}));
|
|
73
|
+
updatedDoc = reducer(updatedDoc, creators.addDocumentType({
|
|
74
|
+
id: "type-2",
|
|
75
|
+
documentType: "powerhouse/b",
|
|
76
|
+
}));
|
|
77
|
+
updatedDoc = reducer(updatedDoc, creators.addDocumentType({
|
|
78
|
+
id: "type-3",
|
|
79
|
+
documentType: "powerhouse/c",
|
|
80
|
+
}));
|
|
81
|
+
expect(updatedDoc.state.global.documentTypes).toHaveLength(3);
|
|
82
|
+
expect(updatedDoc.state.global.documentTypes[0]).toEqual({
|
|
83
|
+
id: "type-1",
|
|
84
|
+
documentType: "powerhouse/a",
|
|
85
|
+
});
|
|
86
|
+
expect(updatedDoc.state.global.documentTypes[1]).toEqual({
|
|
87
|
+
id: "type-2",
|
|
88
|
+
documentType: "powerhouse/b",
|
|
89
|
+
});
|
|
90
|
+
expect(updatedDoc.state.global.documentTypes[2]).toEqual({
|
|
91
|
+
id: "type-3",
|
|
92
|
+
documentType: "powerhouse/c",
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
it("should reject duplicate IDs and store error in operation", () => {
|
|
96
|
+
const input = {
|
|
97
|
+
id: "duplicate",
|
|
98
|
+
documentType: "powerhouse/first",
|
|
99
|
+
};
|
|
100
|
+
let updatedDoc = reducer(document, creators.addDocumentType(input));
|
|
101
|
+
expect(updatedDoc.state.global.documentTypes).toHaveLength(1);
|
|
102
|
+
expect(updatedDoc.operations.global[0].error).toBeUndefined();
|
|
103
|
+
updatedDoc = reducer(updatedDoc, creators.addDocumentType({
|
|
104
|
+
id: "duplicate",
|
|
105
|
+
documentType: "powerhouse/second",
|
|
106
|
+
}));
|
|
107
|
+
expect(updatedDoc.operations.global).toHaveLength(2);
|
|
108
|
+
expect(updatedDoc.operations.global[1].error).toBe('Document type with id "duplicate" already exists');
|
|
109
|
+
expect(updatedDoc.state.global.documentTypes).toHaveLength(1);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe("removeDocumentType", () => {
|
|
113
|
+
it("should mutate state by removing document type from array", () => {
|
|
114
|
+
let updatedDoc = reducer(document, creators.addDocumentType({
|
|
115
|
+
id: "to-remove",
|
|
116
|
+
documentType: "powerhouse/test",
|
|
117
|
+
}));
|
|
118
|
+
updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "to-remove" }));
|
|
119
|
+
expect(updatedDoc.state.global.documentTypes).not.toContainEqual({
|
|
120
|
+
id: "to-remove",
|
|
121
|
+
documentType: "powerhouse/test",
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
it("should remove existing ID", () => {
|
|
125
|
+
let updatedDoc = reducer(document, creators.addDocumentType({
|
|
126
|
+
id: "existing",
|
|
127
|
+
documentType: "powerhouse/test",
|
|
128
|
+
}));
|
|
129
|
+
const lengthBefore = updatedDoc.state.global.documentTypes.length;
|
|
130
|
+
updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "existing" }));
|
|
131
|
+
expect(updatedDoc.state.global.documentTypes.length).toBe(lengthBefore - 1);
|
|
132
|
+
expect(updatedDoc.state.global.documentTypes.find((dt) => dt.id === "existing")).toBeUndefined();
|
|
133
|
+
});
|
|
134
|
+
it("should gracefully handle non-existent ID", () => {
|
|
135
|
+
const initialState = document.state.global.documentTypes;
|
|
136
|
+
const updatedDocument = reducer(document, creators.removeDocumentType({ id: "non-existent-id" }));
|
|
137
|
+
expect(updatedDocument.state.global.documentTypes).toEqual(initialState);
|
|
138
|
+
});
|
|
139
|
+
it("should handle empty array gracefully", () => {
|
|
140
|
+
expect(document.state.global.documentTypes).toEqual([]);
|
|
141
|
+
const updatedDocument = reducer(document, creators.removeDocumentType({ id: "any-id" }));
|
|
142
|
+
expect(updatedDocument.state.global.documentTypes).toEqual([]);
|
|
143
|
+
});
|
|
144
|
+
it("should add then immediately remove item", () => {
|
|
145
|
+
let updatedDoc = reducer(document, creators.addDocumentType({
|
|
146
|
+
id: "temp-type",
|
|
147
|
+
documentType: "powerhouse/temp",
|
|
148
|
+
}));
|
|
149
|
+
updatedDoc = reducer(updatedDoc, creators.removeDocumentType({ id: "temp-type" }));
|
|
150
|
+
expect(updatedDoc.state.global.documentTypes.find((dt) => dt.id === "temp-type")).toBeUndefined();
|
|
151
|
+
expect(updatedDoc.operations.global).toHaveLength(2);
|
|
152
|
+
});
|
|
39
153
|
});
|
|
40
154
|
});
|