@powerhousedao/vetra 4.1.0-dev.82 → 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,95 +2,191 @@
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 setPackageName operation", () => {
17
- const input = generateMock(z.SetPackageNameInputSchema());
18
- const updatedDocument = reducer(document, creators.setPackageName(input));
19
- expect(updatedDocument.operations.global).toHaveLength(1);
20
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_PACKAGE_NAME");
21
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
22
- expect(updatedDocument.operations.global[0].index).toEqual(0);
14
+ describe("setPackageName", () => {
15
+ it("should mutate state with new name", () => {
16
+ const input = { name: "my-package" };
17
+ const updatedDocument = reducer(document, creators.setPackageName(input));
18
+ expect(updatedDocument.state.global.name).toBe("my-package");
19
+ });
23
20
  });
24
- it("should handle setPackageDescription operation", () => {
25
- const input = generateMock(z.SetPackageDescriptionInputSchema());
26
- const updatedDocument = reducer(document, creators.setPackageDescription(input));
27
- expect(updatedDocument.operations.global).toHaveLength(1);
28
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_PACKAGE_DESCRIPTION");
29
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
30
- expect(updatedDocument.operations.global[0].index).toEqual(0);
21
+ describe("setPackageDescription", () => {
22
+ it("should mutate state with new description", () => {
23
+ const input = {
24
+ description: "A test package",
25
+ };
26
+ const updatedDocument = reducer(document, creators.setPackageDescription(input));
27
+ expect(updatedDocument.state.global.description).toBe("A test package");
28
+ });
31
29
  });
32
- it("should handle setPackageCategory operation", () => {
33
- const input = generateMock(z.SetPackageCategoryInputSchema());
34
- const updatedDocument = reducer(document, creators.setPackageCategory(input));
35
- expect(updatedDocument.operations.global).toHaveLength(1);
36
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_PACKAGE_CATEGORY");
37
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
38
- expect(updatedDocument.operations.global[0].index).toEqual(0);
30
+ describe("setPackageCategory", () => {
31
+ it("should mutate state with new category", () => {
32
+ const input = { category: "utility" };
33
+ const updatedDocument = reducer(document, creators.setPackageCategory(input));
34
+ expect(updatedDocument.state.global.category).toBe("utility");
35
+ });
39
36
  });
40
- it("should handle setPackageAuthor operation", () => {
41
- const input = generateMock(z.SetPackageAuthorInputSchema());
42
- const updatedDocument = reducer(document, creators.setPackageAuthor(input));
43
- expect(updatedDocument.operations.global).toHaveLength(1);
44
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_PACKAGE_AUTHOR");
45
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
46
- expect(updatedDocument.operations.global[0].index).toEqual(0);
37
+ describe("setPackageAuthor", () => {
38
+ it("should mutate state with both name and website", () => {
39
+ const input = {
40
+ name: "John Doe",
41
+ website: "https://johndoe.com",
42
+ };
43
+ const updatedDocument = reducer(document, creators.setPackageAuthor(input));
44
+ expect(updatedDocument.state.global.author.name).toBe("John Doe");
45
+ expect(updatedDocument.state.global.author.website).toBe("https://johndoe.com");
46
+ });
47
+ it("should handle partial author data (name only or website only)", () => {
48
+ // Name only
49
+ let updatedDoc = reducer(document, creators.setPackageAuthor({ name: "Jane Doe" }));
50
+ expect(updatedDoc.state.global.author.name).toBe("Jane Doe");
51
+ expect(updatedDoc.state.global.author.website).toBeNull();
52
+ // Website only
53
+ updatedDoc = reducer(updatedDoc, creators.setPackageAuthor({ website: "https://janedoe.com" }));
54
+ expect(updatedDoc.state.global.author.name).toBeNull();
55
+ expect(updatedDoc.state.global.author.website).toBe("https://janedoe.com");
56
+ });
47
57
  });
48
- it("should handle setPackageAuthorName operation", () => {
49
- const input = generateMock(z.SetPackageAuthorNameInputSchema());
50
- const updatedDocument = reducer(document, creators.setPackageAuthorName(input));
51
- expect(updatedDocument.operations.global).toHaveLength(1);
52
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_PACKAGE_AUTHOR_NAME");
53
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
54
- expect(updatedDocument.operations.global[0].index).toEqual(0);
58
+ describe("setPackageAuthorName", () => {
59
+ it("should mutate state with new author name", () => {
60
+ const input = { name: "Alice" };
61
+ const updatedDocument = reducer(document, creators.setPackageAuthorName(input));
62
+ expect(updatedDocument.state.global.author.name).toBe("Alice");
63
+ });
55
64
  });
56
- it("should handle setPackageAuthorWebsite operation", () => {
57
- const input = generateMock(z.SetPackageAuthorWebsiteInputSchema());
58
- const updatedDocument = reducer(document, creators.setPackageAuthorWebsite(input));
59
- expect(updatedDocument.operations.global).toHaveLength(1);
60
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_PACKAGE_AUTHOR_WEBSITE");
61
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
62
- expect(updatedDocument.operations.global[0].index).toEqual(0);
65
+ describe("setPackageAuthorWebsite", () => {
66
+ it("should mutate state with new author website", () => {
67
+ const input = {
68
+ website: "https://example.com",
69
+ };
70
+ const updatedDocument = reducer(document, creators.setPackageAuthorWebsite(input));
71
+ expect(updatedDocument.state.global.author.website).toBe("https://example.com");
72
+ });
63
73
  });
64
- it("should handle addPackageKeyword operation", () => {
65
- const input = generateMock(z.AddPackageKeywordInputSchema());
66
- const updatedDocument = reducer(document, creators.addPackageKeyword(input));
67
- expect(updatedDocument.operations.global).toHaveLength(1);
68
- expect(updatedDocument.operations.global[0].action.type).toBe("ADD_PACKAGE_KEYWORD");
69
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
70
- expect(updatedDocument.operations.global[0].index).toEqual(0);
74
+ describe("addPackageKeyword", () => {
75
+ it("should mutate state by adding keyword to array", () => {
76
+ const input = {
77
+ id: "kw-1",
78
+ label: "react",
79
+ };
80
+ const updatedDocument = reducer(document, creators.addPackageKeyword(input));
81
+ expect(updatedDocument.state.global.keywords).toContainEqual({
82
+ id: "kw-1",
83
+ label: "react",
84
+ });
85
+ });
86
+ it("should add to empty array from initial state", () => {
87
+ expect(document.state.global.keywords).toEqual([]);
88
+ const input = {
89
+ id: "first-kw",
90
+ label: "typescript",
91
+ };
92
+ const updatedDocument = reducer(document, creators.addPackageKeyword(input));
93
+ expect(updatedDocument.state.global.keywords).toEqual([
94
+ { id: "first-kw", label: "typescript" },
95
+ ]);
96
+ });
97
+ it("should add multiple keywords sequentially", () => {
98
+ let updatedDoc = reducer(document, creators.addPackageKeyword({ id: "kw-1", label: "react" }));
99
+ updatedDoc = reducer(updatedDoc, creators.addPackageKeyword({ id: "kw-2", label: "vue" }));
100
+ updatedDoc = reducer(updatedDoc, creators.addPackageKeyword({ id: "kw-3", label: "angular" }));
101
+ expect(updatedDoc.state.global.keywords).toHaveLength(3);
102
+ expect(updatedDoc.state.global.keywords[0]).toEqual({
103
+ id: "kw-1",
104
+ label: "react",
105
+ });
106
+ expect(updatedDoc.state.global.keywords[1]).toEqual({
107
+ id: "kw-2",
108
+ label: "vue",
109
+ });
110
+ expect(updatedDoc.state.global.keywords[2]).toEqual({
111
+ id: "kw-3",
112
+ label: "angular",
113
+ });
114
+ });
115
+ it("should reject duplicate IDs and store error in operation", () => {
116
+ const input = {
117
+ id: "duplicate",
118
+ label: "first",
119
+ };
120
+ let updatedDoc = reducer(document, creators.addPackageKeyword(input));
121
+ expect(updatedDoc.state.global.keywords).toHaveLength(1);
122
+ expect(updatedDoc.operations.global[0].error).toBeUndefined();
123
+ updatedDoc = reducer(updatedDoc, creators.addPackageKeyword({
124
+ id: "duplicate",
125
+ label: "second",
126
+ }));
127
+ expect(updatedDoc.operations.global).toHaveLength(2);
128
+ expect(updatedDoc.operations.global[1].error).toBe('Keyword with id "duplicate" already exists');
129
+ expect(updatedDoc.state.global.keywords).toHaveLength(1);
130
+ });
71
131
  });
72
- it("should handle removePackageKeyword operation", () => {
73
- const input = generateMock(z.RemovePackageKeywordInputSchema());
74
- const updatedDocument = reducer(document, creators.removePackageKeyword(input));
75
- expect(updatedDocument.operations.global).toHaveLength(1);
76
- expect(updatedDocument.operations.global[0].action.type).toBe("REMOVE_PACKAGE_KEYWORD");
77
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
78
- expect(updatedDocument.operations.global[0].index).toEqual(0);
132
+ describe("removePackageKeyword", () => {
133
+ it("should mutate state by removing keyword from array", () => {
134
+ let updatedDoc = reducer(document, creators.addPackageKeyword({
135
+ id: "to-remove",
136
+ label: "test",
137
+ }));
138
+ updatedDoc = reducer(updatedDoc, creators.removePackageKeyword({ id: "to-remove" }));
139
+ expect(updatedDoc.state.global.keywords).not.toContainEqual({
140
+ id: "to-remove",
141
+ label: "test",
142
+ });
143
+ });
144
+ it("should remove existing ID", () => {
145
+ let updatedDoc = reducer(document, creators.addPackageKeyword({
146
+ id: "existing",
147
+ label: "test",
148
+ }));
149
+ const lengthBefore = updatedDoc.state.global.keywords.length;
150
+ updatedDoc = reducer(updatedDoc, creators.removePackageKeyword({ id: "existing" }));
151
+ expect(updatedDoc.state.global.keywords.length).toBe(lengthBefore - 1);
152
+ expect(updatedDoc.state.global.keywords.find((kw) => kw.id === "existing")).toBeUndefined();
153
+ });
154
+ it("should gracefully handle non-existent ID", () => {
155
+ const initialState = document.state.global.keywords;
156
+ const updatedDocument = reducer(document, creators.removePackageKeyword({ id: "non-existent-id" }));
157
+ expect(updatedDocument.state.global.keywords).toEqual(initialState);
158
+ });
159
+ it("should handle empty array gracefully", () => {
160
+ expect(document.state.global.keywords).toEqual([]);
161
+ const updatedDocument = reducer(document, creators.removePackageKeyword({ id: "any-id" }));
162
+ expect(updatedDocument.state.global.keywords).toEqual([]);
163
+ });
164
+ it("should add then immediately remove item", () => {
165
+ let updatedDoc = reducer(document, creators.addPackageKeyword({
166
+ id: "temp-kw",
167
+ label: "temp",
168
+ }));
169
+ updatedDoc = reducer(updatedDoc, creators.removePackageKeyword({ id: "temp-kw" }));
170
+ expect(updatedDoc.state.global.keywords.find((kw) => kw.id === "temp-kw")).toBeUndefined();
171
+ expect(updatedDoc.operations.global).toHaveLength(2);
172
+ });
79
173
  });
80
- it("should handle setPackageGithubUrl operation", () => {
81
- const input = generateMock(z.SetPackageGithubUrlInputSchema());
82
- const updatedDocument = reducer(document, creators.setPackageGithubUrl(input));
83
- expect(updatedDocument.operations.global).toHaveLength(1);
84
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_PACKAGE_GITHUB_URL");
85
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
86
- expect(updatedDocument.operations.global[0].index).toEqual(0);
174
+ describe("setPackageGithubUrl", () => {
175
+ it("should mutate state with new GitHub URL", () => {
176
+ const input = {
177
+ url: "https://github.com/user/repo",
178
+ };
179
+ const updatedDocument = reducer(document, creators.setPackageGithubUrl(input));
180
+ expect(updatedDocument.state.global.githubUrl).toBe("https://github.com/user/repo");
181
+ });
87
182
  });
88
- it("should handle setPackageNpmUrl operation", () => {
89
- const input = generateMock(z.SetPackageNpmUrlInputSchema());
90
- const updatedDocument = reducer(document, creators.setPackageNpmUrl(input));
91
- expect(updatedDocument.operations.global).toHaveLength(1);
92
- expect(updatedDocument.operations.global[0].action.type).toBe("SET_PACKAGE_NPM_URL");
93
- expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
94
- expect(updatedDocument.operations.global[0].index).toEqual(0);
183
+ describe("setPackageNpmUrl", () => {
184
+ it("should mutate state with new npm URL", () => {
185
+ const input = {
186
+ url: "https://npmjs.com/package/my-package",
187
+ };
188
+ const updatedDocument = reducer(document, creators.setPackageNpmUrl(input));
189
+ expect(updatedDocument.state.global.npmUrl).toBe("https://npmjs.com/package/my-package");
190
+ });
95
191
  });
96
192
  });
@@ -2,17 +2,110 @@
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("Vetra Package Document Model", () => {
8
- it("should create a new Vetra Package 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/package");
12
+ expect(document.state.global.name).toBeNull();
13
+ expect(document.state.global.description).toBeNull();
14
+ expect(document.state.global.category).toBeNull();
15
+ expect(document.state.global.author).toEqual({
16
+ name: null,
17
+ website: null,
18
+ });
19
+ expect(document.state.global.keywords).toEqual([]);
20
+ expect(document.state.global.githubUrl).toBeNull();
21
+ expect(document.state.global.npmUrl).toBeNull();
12
22
  });
13
- it("should create a new Vetra Package document with a valid initial state", () => {
23
+ it("should handle multiple operations and maintain consistency", () => {
14
24
  const document = utils.createDocument();
15
- expect(document.state.global).toStrictEqual(initialGlobalState);
16
- expect(document.state.local).toStrictEqual(initialLocalState);
25
+ let updatedDoc = reducer(document, creators.setPackageName({ name: "test-package" }));
26
+ updatedDoc = reducer(updatedDoc, creators.setPackageDescription({ description: "A test package" }));
27
+ updatedDoc = reducer(updatedDoc, creators.setPackageCategory({ category: "utility" }));
28
+ updatedDoc = reducer(updatedDoc, creators.addPackageKeyword({ id: "kw-1", label: "react" }));
29
+ updatedDoc = reducer(updatedDoc, creators.setPackageGithubUrl({
30
+ url: "https://github.com/user/test-package",
31
+ }));
32
+ // Verify state consistency
33
+ expect(updatedDoc.state.global.name).toBe("test-package");
34
+ expect(updatedDoc.state.global.description).toBe("A test package");
35
+ expect(updatedDoc.state.global.category).toBe("utility");
36
+ expect(updatedDoc.state.global.keywords).toHaveLength(1);
37
+ expect(updatedDoc.state.global.githubUrl).toBe("https://github.com/user/test-package");
38
+ });
39
+ it("should handle complete workflow: set metadata, author, and keywords", () => {
40
+ const document = utils.createDocument();
41
+ // Step 1: Set package metadata
42
+ let updatedDoc = reducer(document, creators.setPackageName({ name: "awesome-lib" }));
43
+ updatedDoc = reducer(updatedDoc, creators.setPackageDescription({
44
+ description: "An awesome library for everything",
45
+ }));
46
+ updatedDoc = reducer(updatedDoc, creators.setPackageCategory({ category: "library" }));
47
+ // Step 2: Set author information
48
+ updatedDoc = reducer(updatedDoc, creators.setPackageAuthor({
49
+ name: "Jane Developer",
50
+ website: "https://janedeveloper.com",
51
+ }));
52
+ // Step 3: Add keywords
53
+ updatedDoc = reducer(updatedDoc, creators.addPackageKeyword({ id: "kw-1", label: "javascript" }));
54
+ updatedDoc = reducer(updatedDoc, creators.addPackageKeyword({ id: "kw-2", label: "typescript" }));
55
+ updatedDoc = reducer(updatedDoc, creators.addPackageKeyword({ id: "kw-3", label: "react" }));
56
+ // Step 4: Set repository URLs
57
+ updatedDoc = reducer(updatedDoc, creators.setPackageGithubUrl({
58
+ url: "https://github.com/jane/awesome-lib",
59
+ }));
60
+ updatedDoc = reducer(updatedDoc, creators.setPackageNpmUrl({
61
+ url: "https://npmjs.com/package/awesome-lib",
62
+ }));
63
+ // Verify final state
64
+ expect(updatedDoc.operations.global).toHaveLength(9);
65
+ expect(updatedDoc.state.global.name).toBe("awesome-lib");
66
+ expect(updatedDoc.state.global.author.name).toBe("Jane Developer");
67
+ expect(updatedDoc.state.global.keywords).toHaveLength(3);
68
+ expect(updatedDoc.state.global.githubUrl).toBe("https://github.com/jane/awesome-lib");
69
+ expect(updatedDoc.state.global.npmUrl).toBe("https://npmjs.com/package/awesome-lib");
70
+ });
71
+ describe("Complex Scenarios", () => {
72
+ it("should handle author updates: full then partial", () => {
73
+ const document = utils.createDocument();
74
+ // Set full author
75
+ let updatedDoc = reducer(document, creators.setPackageAuthor({
76
+ name: "John Doe",
77
+ website: "https://johndoe.com",
78
+ }));
79
+ expect(updatedDoc.state.global.author.name).toBe("John Doe");
80
+ expect(updatedDoc.state.global.author.website).toBe("https://johndoe.com");
81
+ // Update only name
82
+ updatedDoc = reducer(updatedDoc, creators.setPackageAuthorName({ name: "Jane Doe" }));
83
+ expect(updatedDoc.state.global.author.name).toBe("Jane Doe");
84
+ expect(updatedDoc.state.global.author.website).toBe("https://johndoe.com");
85
+ // Update only website
86
+ updatedDoc = reducer(updatedDoc, creators.setPackageAuthorWebsite({
87
+ website: "https://janedoe.com",
88
+ }));
89
+ expect(updatedDoc.state.global.author.name).toBe("Jane Doe");
90
+ expect(updatedDoc.state.global.author.website).toBe("https://janedoe.com");
91
+ });
92
+ it("should maintain state integrity with keyword add/remove sequences", () => {
93
+ const document = utils.createDocument();
94
+ // Add multiple keywords
95
+ let updatedDoc = reducer(document, creators.addPackageKeyword({ id: "kw-a", label: "react" }));
96
+ updatedDoc = reducer(updatedDoc, creators.addPackageKeyword({ id: "kw-b", label: "vue" }));
97
+ updatedDoc = reducer(updatedDoc, creators.addPackageKeyword({ id: "kw-c", label: "angular" }));
98
+ expect(updatedDoc.state.global.keywords).toHaveLength(3);
99
+ // Remove middle one
100
+ updatedDoc = reducer(updatedDoc, creators.removePackageKeyword({ id: "kw-b" }));
101
+ expect(updatedDoc.state.global.keywords).toHaveLength(2);
102
+ // Add it back with new label value
103
+ updatedDoc = reducer(updatedDoc, creators.addPackageKeyword({ id: "kw-b", label: "svelte" }));
104
+ expect(updatedDoc.state.global.keywords).toHaveLength(3);
105
+ // Verify order and content
106
+ const keywordB = updatedDoc.state.global.keywords.find((kw) => kw.id === "kw-b");
107
+ expect(keywordB?.label).toBe("svelte");
108
+ // Verify operation history
109
+ });
17
110
  });
18
111
  });
@@ -1 +1 @@
1
- {"version":3,"file":"AppEditorForm.d.ts","sourceRoot":"","sources":["../../../../editors/app-editor/components/AppEditorForm.tsx"],"names":[],"mappings":"AAcA,eAAO,MAAM,aAAa,+CAmOzB,CAAC"}
1
+ {"version":3,"file":"AppEditorForm.d.ts","sourceRoot":"","sources":["../../../../editors/app-editor/components/AppEditorForm.tsx"],"names":[],"mappings":"AAcA,eAAO,MAAM,aAAa,+CA2OzB,CAAC"}
@@ -96,9 +96,9 @@ export const AppEditorForm = () => {
96
96
  handleAddDocumentType(selectedValue);
97
97
  }
98
98
  };
99
- return (_jsxs("div", { className: "space-y-6 bg-white p-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h2", { className: "text-lg font-medium text-gray-900", children: "App Configuration" }), _jsx(StatusPill, { status: status === "CONFIRMED" ? "confirmed" : "draft", label: status === "CONFIRMED" ? "Confirmed" : "Draft" })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-2 block text-sm font-medium text-gray-700", children: "App Name" }), _jsx("input", { type: "text", value: appName, onChange: (e) => setAppName(e.target.value), disabled: isReadOnly, className: `w-full rounded-md border border-gray-300 px-3 py-2 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500 ${isReadOnly ? "cursor-not-allowed bg-gray-100" : ""}`, placeholder: "Enter app name" })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-2 block text-sm font-medium text-gray-700", children: "Document Types" }), _jsxs("div", { className: "space-y-2", children: [!isReadOnly && (_jsxs("select", { onChange: (e) => handleDocumentTypeSelection(e.target.value), className: "w-full rounded-md border border-gray-300 px-3 py-2 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { children: "Select a document type to add" }), _jsx("option", { children: "--- Vetra drive document types ---" }), _jsx("option", { value: ALL_IN_DRIVE, children: "Add all document types in Vetra drive" }), documentTypesInSelectedDrive
99
+ return (_jsxs("div", { className: "space-y-6 bg-white p-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h2", { className: "text-lg font-medium text-gray-900", children: "App Configuration" }), _jsx(StatusPill, { status: status === "CONFIRMED" ? "confirmed" : "draft", label: status === "CONFIRMED" ? "Confirmed" : "Draft" })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "app-name", className: "mb-2 block text-sm font-medium text-gray-700", children: "App Name" }), _jsx("input", { id: "app-name", type: "text", value: appName, onChange: (e) => setAppName(e.target.value), disabled: isReadOnly, className: `w-full rounded-md border border-gray-300 px-3 py-2 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500 ${isReadOnly ? "cursor-not-allowed bg-gray-100" : ""}`, placeholder: "Enter app name" })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "document-types", className: "mb-2 block text-sm font-medium text-gray-700", children: "Document Types" }), _jsxs("div", { className: "space-y-2", children: [!isReadOnly && (_jsxs("select", { onChange: (e) => handleDocumentTypeSelection(e.target.value), className: "w-full rounded-md border border-gray-300 px-3 py-2 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { children: "Select a document type to add" }), _jsx("option", { children: "--- Vetra drive document types ---" }), _jsx("option", { value: ALL_IN_DRIVE, children: "Add all document types in Vetra drive" }), documentTypesInSelectedDrive
100
100
  ?.filter((dt) => !selectedDocumentTypes.includes(dt))
101
101
  .map((docType) => (_jsx("option", { value: docType, children: docType }, docType))), _jsx("option", { children: "--- Reactor document types ---" }), _jsx("option", { value: ALL_IN_REACTOR, children: "Add all document types in Reactor" }), supportedDocumentTypesInReactor
102
102
  ?.filter((dt) => !selectedDocumentTypes.includes(dt))
103
- .map((docType) => (_jsx("option", { value: docType, children: docType }, docType))), _jsx("option", { children: "--- Allow any document type ---" }), _jsx("option", { value: ALLOW_ANY, children: "Allow any document type" })] })), _jsx("div", { className: "space-y-1", children: selectedDocumentTypes.length > 0 ? (selectedDocumentTypes.map((type) => (_jsxs("div", { className: "flex items-center py-1", children: [_jsx("span", { className: "text-sm text-gray-700", children: type }), !isReadOnly && (_jsx("button", { onClick: () => handleRemoveDocumentType(type), className: "ml-2 text-gray-400 hover:text-gray-600 focus:outline-none", children: "\u00D7" }))] }, type)))) : (_jsx("span", { className: "text-sm text-gray-700", children: "All documents (*)" })) })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-md mb-4 font-medium text-gray-900", children: "Drag and Drop Settings" }), _jsx("div", { className: "mb-4", children: _jsxs("label", { className: "flex items-center", children: [_jsx("input", { type: "checkbox", checked: isDragAndDropEnabled, onChange: (e) => onDragAndDropToggle(e.target.checked), disabled: isReadOnly, className: `mr-2 h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 ${isReadOnly ? "cursor-not-allowed" : ""}` }), _jsx("span", { className: "text-sm font-medium text-gray-700", children: "Enable drag and drop" })] }) })] }), !isReadOnly && (_jsx("div", { children: _jsx("button", { onClick: handleConfirm, disabled: !appName.trim(), className: "rounded-md bg-blue-600 px-4 py-2 text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:bg-gray-300", children: "Confirm" }) }))] }));
103
+ .map((docType) => (_jsx("option", { value: docType, children: docType }, docType))), _jsx("option", { children: "--- Allow any document type ---" }), _jsx("option", { value: ALLOW_ANY, children: "Allow any document type" })] })), _jsx("div", { className: "space-y-1", children: selectedDocumentTypes.length > 0 ? (selectedDocumentTypes.map((type) => (_jsxs("div", { className: "flex items-center py-1", children: [_jsx("span", { className: "text-sm text-gray-700", children: type }), !isReadOnly && (_jsx("button", { onClick: () => handleRemoveDocumentType(type), className: "ml-2 text-gray-400 hover:text-gray-600 focus:outline-none", children: "\u00D7" }))] }, type)))) : (_jsx("span", { className: "text-sm text-gray-700", children: "All documents (*)" })) })] })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-md mb-4 font-medium text-gray-900", children: "Drag and Drop Settings" }), _jsx("div", { className: "mb-4", children: _jsxs("label", { htmlFor: "drag-and-drop-enabled", className: "flex items-center", children: [_jsx("input", { id: "drag-and-drop-enabled", type: "checkbox", checked: isDragAndDropEnabled, onChange: (e) => onDragAndDropToggle(e.target.checked), disabled: isReadOnly, className: `mr-2 h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 ${isReadOnly ? "cursor-not-allowed" : ""}` }), _jsx("span", { className: "text-sm font-medium text-gray-700", children: "Enable drag and drop" })] }) })] }), !isReadOnly && (_jsx("div", { children: _jsx("button", { onClick: handleConfirm, disabled: !appName.trim(), className: "rounded-md bg-blue-600 px-4 py-2 text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:bg-gray-300", children: "Confirm" }) }))] }));
104
104
  };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=editor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.test.d.ts","sourceRoot":"","sources":["../../../editors/app-editor/editor.test.tsx"],"names":[],"mappings":""}