@griddo/ax 11.10.23 → 11.10.24

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 (58) hide show
  1. package/config/griddo-config/index.js +1 -0
  2. package/package.json +2 -2
  3. package/src/Style/index.tsx +10 -8
  4. package/src/__tests__/components/ConfigPanel/ConfigPanel.test.tsx +10 -8
  5. package/src/__tests__/components/ConfigPanel/Form/ConnectedField/PageConnectedField/PageConnectedField.test.tsx +86 -8
  6. package/src/__tests__/components/SideModal/SideModal.test.tsx +64 -0
  7. package/src/__tests__/hooks/useSchemas.test.tsx +224 -0
  8. package/src/__tests__/services/SchemasService.test.ts +135 -0
  9. package/src/api/schemas.tsx +11 -1
  10. package/src/components/ConfigPanel/GlobalPageForm/index.tsx +11 -17
  11. package/src/components/Fields/Wysiwyg/helpers.tsx +14 -4
  12. package/src/components/Loader/components/Dots.js +4 -5
  13. package/src/components/PageFinder/index.tsx +15 -9
  14. package/src/components/ResizePanel/index.tsx +13 -3
  15. package/src/components/ResizePanel/style.tsx +2 -9
  16. package/src/containers/App/actions.tsx +96 -24
  17. package/src/containers/App/constants.tsx +7 -0
  18. package/src/containers/App/interfaces.tsx +26 -8
  19. package/src/containers/App/reducer.tsx +24 -9
  20. package/src/containers/Sites/actions.tsx +49 -49
  21. package/src/forms/editor.tsx +4 -3
  22. package/src/helpers/index.tsx +76 -94
  23. package/src/helpers/schemas.tsx +144 -36
  24. package/src/helpers/structuredData.tsx +36 -7
  25. package/src/helpers/themes.tsx +26 -8
  26. package/src/hooks/index.tsx +5 -0
  27. package/src/hooks/useSchemas.ts +151 -0
  28. package/src/locales/en-US.ts +1 -0
  29. package/src/locales/es-ES.ts +1 -0
  30. package/src/modules/Analytics/GroupPanel/index.tsx +9 -6
  31. package/src/modules/Analytics/GroupPanel/utils.tsx +12 -28
  32. package/src/modules/Content/PageItem/index.tsx +33 -36
  33. package/src/modules/Content/index.tsx +34 -30
  34. package/src/modules/Content/utils.tsx +16 -12
  35. package/src/modules/Forms/FormEditor/index.tsx +13 -14
  36. package/src/modules/FramePreview/index.tsx +8 -8
  37. package/src/modules/GlobalEditor/index.tsx +57 -42
  38. package/src/modules/MediaGallery/ImageModal/index.tsx +15 -9
  39. package/src/modules/MediaGallery/ImageModal/style.tsx +16 -1
  40. package/src/modules/PublicPreview/index.tsx +4 -3
  41. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +4 -5
  42. package/src/modules/Settings/Globals/index.tsx +10 -11
  43. package/src/modules/Sites/index.tsx +13 -5
  44. package/src/modules/StructuredData/Form/index.tsx +25 -29
  45. package/src/modules/StructuredData/StructuredDataList/OptionTable/index.tsx +15 -6
  46. package/src/modules/StructuredData/StructuredDataList/index.tsx +22 -14
  47. package/src/modules/StructuredData/StructuredDataList/utils.tsx +12 -11
  48. package/src/schemas/index.tsx +5 -4
  49. package/src/schemas/pages/Page.ts +308 -0
  50. package/src/schemas/pages/index.ts +9 -0
  51. package/src/services/SchemasService.ts +240 -0
  52. package/src/services/index.ts +9 -0
  53. package/src/types/index.tsx +48 -39
  54. package/tsconfig.paths.json +1 -0
  55. package/src/schemas/pages/Page.tsx +0 -301
  56. package/src/schemas/pages/index.tsx +0 -5
  57. /package/src/schemas/pages/{FormPage.tsx → FormPage.ts} +0 -0
  58. /package/src/schemas/pages/{GlobalPage.tsx → GlobalPage.ts} +0 -0
@@ -87,6 +87,7 @@ const griddoAxAliases = {
87
87
  "@ax/routes": path.resolve(__dirname, "../../src/routes"),
88
88
  "@ax/types": path.resolve(__dirname, "../../src/types"),
89
89
  "@ax/schemas": path.resolve(__dirname, "../../src/schemas"),
90
+ "@ax/services": path.resolve(__dirname, "../../src/services"),
90
91
  "@ax/locales": path.resolve(__dirname, "../../src/locales"),
91
92
  };
92
93
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "11.10.23",
4
+ "version": "11.10.24",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Diego M. Béjar <diego.bejar@secuoyas.com>",
@@ -217,5 +217,5 @@
217
217
  "publishConfig": {
218
218
  "access": "public"
219
219
  },
220
- "gitHead": "a1d9b179dfa6ba29d534aba13f4c61267c17926a"
220
+ "gitHead": "4d88c4e8c6c325193a737ee2822c55b9659986ae"
221
221
  }
@@ -1,11 +1,11 @@
1
- import * as React from "react";
2
-
3
- import { ThemeProvider, createGlobalStyle } from "styled-components";
4
1
  import { parseTheme } from "@ax/helpers";
5
- import reset from "styled-reset";
2
+
6
3
  import { normalize } from "polished";
7
- import fonts from "./fonts";
4
+ import { createGlobalStyle, ThemeProvider } from "styled-components";
5
+ import reset from "styled-reset";
6
+
8
7
  import globalTheme from "../themes/theme.json";
8
+ import fonts from "./fonts";
9
9
 
10
10
  const GlobalStyle = createGlobalStyle`
11
11
  ${reset}
@@ -25,9 +25,11 @@ const GlobalStyle = createGlobalStyle`
25
25
  body {
26
26
  min-width: 1280px;
27
27
  }
28
- body.no-select {
29
- user-select: none !important;
30
- }
28
+
29
+ /* Resize panel helper classes */
30
+ body.no-select { cursor: col-resize !important; user-select: none !important; }
31
+ body.no-select * { cursor: col-resize !important; pointer-events: none !important; }
32
+
31
33
  * { box-sizing: border-box; }
32
34
  a { color: inherit; text-decoration: none; }
33
35
  img { display: block; width: 100%; max-width: 100%; }
@@ -1,19 +1,20 @@
1
- import * as React from "react";
2
-
3
- import { ThemeProvider } from "styled-components";
4
- import { render, cleanup, screen } from "../../../../config/jest/test-utils";
5
1
  import { mock } from "jest-mock-extended";
6
2
  import configureStore from "redux-mock-store";
3
+ import thunk from "redux-thunk";
4
+ import { ThemeProvider } from "styled-components";
5
+
7
6
  import "@testing-library/jest-dom";
8
7
 
8
+ import ConfigPanel, { type IStateProps } from "@ax/components/ConfigPanel";
9
9
  import { parseTheme } from "@ax/helpers";
10
- import ConfigPanel, { IStateProps } from "@ax/components/ConfigPanel";
11
10
  import globalTheme from "@ax/themes/theme.json";
11
+
12
+ import { cleanup, render, screen } from "../../../../config/jest/test-utils";
12
13
  import { defaultStore } from "./../../../__mocks__/store/GenericStore";
13
14
 
14
15
  afterEach(cleanup);
15
16
 
16
- const middlewares: any = [];
17
+ const middlewares: any = [thunk];
17
18
  const mockStore = configureStore(middlewares);
18
19
  const initialStore = {
19
20
  ...defaultStore,
@@ -136,6 +137,9 @@ defaultProps.schema = {
136
137
  },
137
138
  ],
138
139
  };
140
+ defaultProps.setSelectedTab.mockImplementation((tab) => {
141
+ console.log("Tab seleccionada:", tab);
142
+ });
139
143
  defaultProps.actions = { deleteModule: jest.fn() };
140
144
  defaultProps.breadcrumb = [
141
145
  {
@@ -146,9 +150,7 @@ defaultProps.breadcrumb = [
146
150
  ];
147
151
  defaultProps.selectedParent = null;
148
152
  defaultProps.activatedModules = ["Accordion", "AddressCollection"];
149
- const setSelectedContentMock = defaultProps.setSelectedContent as jest.MockedFunction<(editorID: number) => void>;
150
153
  defaultProps.selectedTab = "content";
151
- const setSelectedTabMocked = defaultProps.setSelectedTab as jest.MockedFunction<(tab: string) => void>;
152
154
  defaultProps.isPage = false;
153
155
  defaultProps.isEditable = true;
154
156
  defaultProps.theme = "default-theme";
@@ -1,16 +1,16 @@
1
- import * as React from "react";
2
1
  import axios from "axios";
3
-
4
- import { ThemeProvider } from "styled-components";
5
- import { render, cleanup, screen, fireEvent } from "../../../../../../../config/jest/test-utils";
6
2
  import configureStore from "redux-mock-store";
3
+ import { ThemeProvider } from "styled-components";
4
+
5
+ import { cleanup, fireEvent, render, screen } from "../../../../../../../config/jest/test-utils";
7
6
  import "@testing-library/jest-dom";
8
- import thunk from "redux-thunk";
9
7
 
10
- import { parseTheme } from "@ax/helpers";
11
8
  import PageConnectedField from "@ax/components/ConfigPanel/Form/ConnectedField/PageConnectedField";
9
+ import { parseTheme } from "@ax/helpers";
12
10
  import globalTheme from "@ax/themes/theme.json";
13
11
 
12
+ import thunk from "redux-thunk";
13
+
14
14
  beforeEach(() => {
15
15
  cleanup();
16
16
  });
@@ -18,6 +18,73 @@ beforeEach(() => {
18
18
  jest.mock("axios");
19
19
  const mockedAxios = axios as jest.MockedFunction<typeof axios>;
20
20
 
21
+ // Mock schemasService to prevent access to undefined config and ensure all helper functions work
22
+ jest.mock("@ax/services", () => ({
23
+ schemasService: {
24
+ isLoaded: jest.fn(() => true),
25
+ getSchemas: jest.fn(() => ({
26
+ ui: {
27
+ modules: {},
28
+ components: {},
29
+ templates: {
30
+ BasicTemplate: {
31
+ component: "BasicTemplate",
32
+ displayName: "Basic Template",
33
+ type: "template",
34
+ default: {},
35
+ config: [
36
+ {
37
+ title: "Template Options",
38
+ key: "templateOptions",
39
+ type: "TextField",
40
+ },
41
+ ],
42
+ },
43
+ },
44
+ },
45
+ config: {
46
+ themes: [
47
+ {
48
+ value: "default",
49
+ label: "Default Theme",
50
+ default: true,
51
+ },
52
+ ],
53
+ moduleCategories: [
54
+ {
55
+ label: "Header",
56
+ value: "header",
57
+ featured: true,
58
+ },
59
+ ],
60
+ menuItems: {},
61
+ richTextConfig: {},
62
+ },
63
+ contentTypes: {
64
+ dataPacks: {},
65
+ structuredData: {},
66
+ },
67
+ forms: {
68
+ templates: {},
69
+ categories: [],
70
+ fields: {},
71
+ },
72
+ languages: [],
73
+ languagesDefinition: {},
74
+ version: "1.0.0",
75
+ defaultLanguage: { id: 1, locale: "en", language: "English", label: "English", isDefault: true },
76
+ })),
77
+ setSchemas: jest.fn(),
78
+ clear: jest.fn(),
79
+ },
80
+ }));
81
+
82
+ // Mock schemas to prevent getPageSchemas from accessing schemasService
83
+ jest.mock("@ax/schemas", () => ({
84
+ getPageSchemas: jest.fn(() => ({})),
85
+ getFixedSchemas: jest.fn(() => ({})),
86
+ }));
87
+
21
88
  const middlewares: any = [thunk];
22
89
  const mockStore = configureStore(middlewares);
23
90
  const updateEditorContentMock = jest.fn();
@@ -117,6 +184,13 @@ const templateProps = {
117
184
  title: "Header",
118
185
  component: "Header",
119
186
  type: "header",
187
+ config: [
188
+ {
189
+ title: "Template Options",
190
+ key: "templateOptions",
191
+ type: "TextField",
192
+ },
193
+ ],
120
194
  configTabs: [
121
195
  {
122
196
  title: "content",
@@ -136,6 +210,7 @@ const templateProps = {
136
210
  isGlobal: true,
137
211
  selectedTab: "config",
138
212
  theme: "default-theme",
213
+ isForm: false,
139
214
  };
140
215
 
141
216
  const data = {
@@ -174,8 +249,11 @@ describe("PageConnectedField component rendering", () => {
174
249
  { store },
175
250
  );
176
251
 
177
- const templateText = screen.getByText(/Template Options/i);
178
- expect(templateText).toBeInTheDocument();
252
+ // Check that "Template Options" title is rendered
253
+ const templateTitles = screen.getAllByText("Template Options");
254
+ expect(templateTitles).toHaveLength(2); // Title and label
255
+ const titleElement = templateTitles[0]; // First one should be the title
256
+ expect(titleElement.tagName).toBe("P");
179
257
  });
180
258
 
181
259
  it("should call getPageBreadCrumb", () => {
@@ -8,6 +8,57 @@ import { parseTheme } from "@ax/helpers";
8
8
  import SideModal, { ISideModalProps } from "@ax/components/SideModal";
9
9
  import globalTheme from "@ax/themes/theme.json";
10
10
 
11
+ // Mock schemasService to prevent access to undefined schemas
12
+ jest.mock("@ax/services", () => ({
13
+ schemasService: {
14
+ isLoaded: jest.fn(() => true),
15
+ getSchemas: jest.fn(() => ({
16
+ ui: {
17
+ modules: {
18
+ BasicContent: {
19
+ displayName: "Basic Content",
20
+ component: "BasicContent",
21
+ type: "module",
22
+ category: "content",
23
+ },
24
+ CardCollection: {
25
+ displayName: "Card Collection",
26
+ component: "CardCollection",
27
+ type: "module",
28
+ category: "content",
29
+ },
30
+ },
31
+ components: {},
32
+ templates: {},
33
+ },
34
+ config: {
35
+ themes: [],
36
+ moduleCategories: [],
37
+ menuItems: {},
38
+ },
39
+ contentTypes: {
40
+ dataPacks: {},
41
+ },
42
+ forms: {
43
+ templates: {},
44
+ categories: [],
45
+ },
46
+ languages: [],
47
+ languagesDefinition: {},
48
+ version: "1.0.0",
49
+ defaultLanguage: { id: 1, locale: "en", language: "English", label: "English", isDefault: true },
50
+ })),
51
+ setSchemas: jest.fn(),
52
+ clear: jest.fn(),
53
+ },
54
+ }));
55
+
56
+ // Mock schemas to prevent getPageSchemas from accessing schemasService
57
+ jest.mock("@ax/schemas", () => ({
58
+ getPageSchemas: jest.fn(() => ({})),
59
+ getFixedSchemas: jest.fn(() => ({})),
60
+ }));
61
+
11
62
  afterEach(cleanup);
12
63
 
13
64
  const defaultProps = mock<ISideModalProps>();
@@ -277,6 +328,19 @@ describe("SideModal component events", () => {
277
328
  });
278
329
 
279
330
  it("should filter by query", () => {
331
+ const handleClickMock = jest.fn();
332
+ const toggleModalMock = jest.fn() as CalledWithMock<void, []> & (() => void);
333
+ defaultProps.categories = [
334
+ { featured: true, label: "All", value: "all" },
335
+ { label: "Content", value: "content" },
336
+ { label: "Collections", value: "collections" },
337
+ ];
338
+ defaultProps.isOpen = true;
339
+ defaultProps.theme = "default-theme";
340
+ defaultProps.whiteList = ["BasicContent", "CardCollection"];
341
+ defaultProps.onClick = handleClickMock;
342
+ defaultProps.toggleModal = toggleModalMock;
343
+ defaultProps.optionsType = "modules";
280
344
  defaultProps.showSearch = true;
281
345
 
282
346
  render(
@@ -0,0 +1,224 @@
1
+ import { Provider } from "react-redux";
2
+
3
+ import * as AppActions from "@ax/containers/App/actions";
4
+ import { useSchemas } from "@ax/hooks";
5
+ import type { ISchemas } from "@ax/services";
6
+ import { schemasService } from "@ax/services";
7
+
8
+ import { renderHook } from "@testing-library/react";
9
+ import configureStore from "redux-mock-store";
10
+ import thunk from "redux-thunk";
11
+
12
+ // Mock del servicio
13
+ jest.mock("@ax/services", () => ({
14
+ schemasService: {
15
+ isLoaded: jest.fn(),
16
+ getSchemas: jest.fn(),
17
+ clear: jest.fn(),
18
+ },
19
+ }));
20
+
21
+ // Mock de la acción loadSchemas
22
+ jest.mock("@ax/containers/App/actions", () => ({
23
+ loadSchemas: jest.fn(() => ({
24
+ type: "LOAD_SCHEMAS",
25
+ })),
26
+ }));
27
+
28
+ const middlewares = [thunk];
29
+ const mockStore = configureStore(middlewares);
30
+
31
+ describe("useSchemas hook", () => {
32
+ beforeEach(() => {
33
+ jest.clearAllMocks();
34
+ (schemasService.clear as jest.Mock).mockImplementation(() => {});
35
+ });
36
+
37
+ const createWrapper = (store: ReturnType<typeof mockStore>) => {
38
+ return ({ children }: { children: React.ReactNode }) => <Provider store={store}>{children}</Provider>;
39
+ };
40
+
41
+ it("should return null schemas when not loaded", () => {
42
+ const initialState = {
43
+ app: {
44
+ schemasLoading: false,
45
+ schemasError: null,
46
+ },
47
+ };
48
+
49
+ const store = mockStore(initialState);
50
+ (schemasService.isLoaded as jest.Mock).mockReturnValue(false);
51
+
52
+ const { result } = renderHook(() => useSchemas(), {
53
+ wrapper: createWrapper(store),
54
+ });
55
+
56
+ expect(result.current.schemas).toBe(null);
57
+ expect(result.current.isLoading).toBe(false);
58
+ expect(result.current.error).toBe(null);
59
+ });
60
+
61
+ it("should return schemas when service is loaded", () => {
62
+ const mockSchemas: ISchemas = {
63
+ ui: {
64
+ modules: {},
65
+ components: {},
66
+ templates: {},
67
+ },
68
+ config: {
69
+ themes: [],
70
+ moduleCategories: [],
71
+ menuItems: {},
72
+ },
73
+ contentTypes: {
74
+ dataPacks: {},
75
+ },
76
+ languagesDefinition: {},
77
+ version: "1.0.0",
78
+ languages: [
79
+ {
80
+ id: 1,
81
+ locale: "en-US",
82
+ language: "en",
83
+ label: "English",
84
+ isDefault: true,
85
+ },
86
+ ],
87
+ defaultLanguage: {
88
+ id: 1,
89
+ locale: "en-US",
90
+ language: "en",
91
+ label: "English",
92
+ isDefault: true,
93
+ },
94
+ };
95
+
96
+ const initialState = {
97
+ app: {
98
+ schemasLoading: false,
99
+ schemasError: null,
100
+ },
101
+ };
102
+
103
+ const store = mockStore(initialState);
104
+ (schemasService.isLoaded as jest.Mock).mockReturnValue(true);
105
+ (schemasService.getSchemas as jest.Mock).mockReturnValue(mockSchemas);
106
+
107
+ const { result } = renderHook(() => useSchemas(), {
108
+ wrapper: createWrapper(store),
109
+ });
110
+
111
+ expect(result.current.schemas).toEqual(mockSchemas);
112
+ expect(result.current.isLoading).toBe(false);
113
+ expect(result.current.error).toBe(null);
114
+ });
115
+
116
+ it("should dispatch loadSchemas action on mount", () => {
117
+ const initialState = {
118
+ app: {
119
+ schemasLoading: false,
120
+ schemasError: null,
121
+ },
122
+ };
123
+
124
+ const store = mockStore(initialState);
125
+ (schemasService.isLoaded as jest.Mock).mockReturnValue(false);
126
+
127
+ renderHook(() => useSchemas(), {
128
+ wrapper: createWrapper(store),
129
+ });
130
+
131
+ const actions = store.getActions();
132
+ expect(actions).toEqual([{ type: "LOAD_SCHEMAS" }]);
133
+ expect(AppActions.loadSchemas).toHaveBeenCalled();
134
+ });
135
+
136
+ it("should return loading state when schemasLoading is true", () => {
137
+ const initialState = {
138
+ app: {
139
+ schemasLoading: true,
140
+ schemasError: null,
141
+ },
142
+ };
143
+
144
+ const store = mockStore(initialState);
145
+ (schemasService.isLoaded as jest.Mock).mockReturnValue(false);
146
+
147
+ const { result } = renderHook(() => useSchemas(), {
148
+ wrapper: createWrapper(store),
149
+ });
150
+
151
+ expect(result.current.isLoading).toBe(true);
152
+ });
153
+
154
+ it("should return error state when schemasError is set", () => {
155
+ const errorMessage = "Failed to load schemas";
156
+
157
+ const initialState = {
158
+ app: {
159
+ schemasLoading: false,
160
+ schemasError: errorMessage,
161
+ },
162
+ };
163
+
164
+ const store = mockStore(initialState);
165
+ (schemasService.isLoaded as jest.Mock).mockReturnValue(false);
166
+
167
+ const { result } = renderHook(() => useSchemas(), {
168
+ wrapper: createWrapper(store),
169
+ });
170
+
171
+ expect(result.current.error).toBe(errorMessage);
172
+ expect(result.current.isLoading).toBe(false);
173
+ });
174
+
175
+ it("should handle error when getSchemas throws", () => {
176
+ const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {});
177
+
178
+ const initialState = {
179
+ app: {
180
+ schemasLoading: false,
181
+ schemasError: null,
182
+ },
183
+ };
184
+
185
+ const store = mockStore(initialState);
186
+ (schemasService.isLoaded as jest.Mock).mockReturnValue(true);
187
+ (schemasService.getSchemas as jest.Mock).mockImplementation(() => {
188
+ throw new Error("Failed to get schemas");
189
+ });
190
+
191
+ const { result } = renderHook(() => useSchemas(), {
192
+ wrapper: createWrapper(store),
193
+ });
194
+
195
+ expect(result.current.schemas).toBe(null);
196
+ expect(consoleErrorSpy).toHaveBeenCalled();
197
+
198
+ consoleErrorSpy.mockRestore();
199
+ });
200
+
201
+ it("should NOT re-dispatch loadSchemas on re-render", () => {
202
+ const initialState = {
203
+ app: {
204
+ schemasLoading: false,
205
+ schemasError: null,
206
+ },
207
+ };
208
+
209
+ const store = mockStore(initialState);
210
+ (schemasService.isLoaded as jest.Mock).mockReturnValue(false);
211
+
212
+ const { rerender } = renderHook(() => useSchemas(), {
213
+ wrapper: createWrapper(store),
214
+ });
215
+
216
+ expect(AppActions.loadSchemas).toHaveBeenCalledTimes(1);
217
+
218
+ jest.clearAllMocks();
219
+
220
+ rerender();
221
+
222
+ expect(AppActions.loadSchemas).not.toHaveBeenCalled();
223
+ });
224
+ });
@@ -0,0 +1,135 @@
1
+ import { type ISchemas, schemasService } from "@ax/services";
2
+
3
+ describe("SchemasService", () => {
4
+ beforeEach(() => {
5
+ // Limpiar el estado del servicio antes de cada test
6
+ schemasService.clear();
7
+ });
8
+
9
+ describe("isLoaded", () => {
10
+ it("should return false initially", () => {
11
+ expect(schemasService.isLoaded()).toBe(false);
12
+ });
13
+
14
+ it("should return true after schemas are set", () => {
15
+ const mockSchemas = createMockSchemas();
16
+ schemasService.setSchemas(mockSchemas);
17
+ expect(schemasService.isLoaded()).toBe(true);
18
+ });
19
+
20
+ it("should return false after clear is called", () => {
21
+ const mockSchemas = createMockSchemas();
22
+ schemasService.setSchemas(mockSchemas);
23
+ schemasService.clear();
24
+ expect(schemasService.isLoaded()).toBe(false);
25
+ });
26
+ });
27
+
28
+ describe("getSchemas", () => {
29
+ it("should throw SchemasNotLoadedError when schemas are not loaded", () => {
30
+ let error: Error | undefined;
31
+ try {
32
+ schemasService.getSchemas();
33
+ } catch (e) {
34
+ error = e as Error;
35
+ }
36
+
37
+ expect(error).toBeDefined();
38
+ expect(error).toBeInstanceOf(Error);
39
+ expect(error?.name).toBe("SchemasNotLoadedError");
40
+ expect(error?.message).toBe("Schemas have not been loaded yet. Call loadSchemas() first.");
41
+ });
42
+
43
+ it("should return the schemas after they are set", () => {
44
+ const mockSchemas = createMockSchemas();
45
+ schemasService.setSchemas(mockSchemas);
46
+ const retrievedSchemas = schemasService.getSchemas();
47
+ expect(retrievedSchemas).toEqual(mockSchemas);
48
+ });
49
+ });
50
+
51
+ describe("setSchemas", () => {
52
+ it("should store schemas correctly", () => {
53
+ const mockSchemas = createMockSchemas();
54
+ schemasService.setSchemas(mockSchemas);
55
+ expect(schemasService.isLoaded()).toBe(true);
56
+ expect(schemasService.getSchemas()).toEqual(mockSchemas);
57
+ });
58
+
59
+ it("should overwrite existing schemas", () => {
60
+ const firstSchemas = createMockSchemas("1.0.0");
61
+ const secondSchemas = createMockSchemas("2.0.0");
62
+ schemasService.setSchemas(firstSchemas);
63
+ schemasService.setSchemas(secondSchemas);
64
+ expect(schemasService.getSchemas().version).toBe("2.0.0");
65
+ });
66
+ });
67
+
68
+ describe("clear", () => {
69
+ it("should clear stored schemas", () => {
70
+ const mockSchemas = createMockSchemas();
71
+ schemasService.setSchemas(mockSchemas);
72
+ expect(schemasService.isLoaded()).toBe(true);
73
+ schemasService.clear();
74
+ expect(schemasService.isLoaded()).toBe(false);
75
+
76
+ let error: Error | undefined;
77
+ try {
78
+ schemasService.getSchemas();
79
+ } catch (e) {
80
+ error = e as Error;
81
+ }
82
+
83
+ expect(error).toBeDefined();
84
+ expect(error).toBeInstanceOf(Error);
85
+ expect(error?.name).toBe("SchemasNotLoadedError");
86
+ });
87
+ });
88
+
89
+ describe("getInstanceId", () => {
90
+ it("should return a string instance ID", () => {
91
+ const instanceId = schemasService.getInstanceId();
92
+ expect(typeof instanceId).toBe("string");
93
+ expect(instanceId.length).toBeGreaterThan(0);
94
+ });
95
+ });
96
+ });
97
+
98
+ /**
99
+ * Helper function to create a mock ISchemas object for testing
100
+ */
101
+ function createMockSchemas(version = "1.0.0"): ISchemas {
102
+ return {
103
+ ui: {
104
+ modules: {},
105
+ components: {},
106
+ templates: {},
107
+ },
108
+ config: {
109
+ themes: [],
110
+ moduleCategories: [],
111
+ menuItems: {},
112
+ },
113
+ contentTypes: {
114
+ dataPacks: {},
115
+ },
116
+ languagesDefinition: {},
117
+ version,
118
+ languages: [
119
+ {
120
+ id: 1,
121
+ locale: "en-US",
122
+ language: "en",
123
+ label: "English",
124
+ isDefault: true,
125
+ },
126
+ ],
127
+ defaultLanguage: {
128
+ id: 1,
129
+ locale: "en-US",
130
+ language: "en",
131
+ label: "English",
132
+ isDefault: true,
133
+ },
134
+ };
135
+ }
@@ -1,5 +1,5 @@
1
1
  import { template } from "./config";
2
- import { IServiceConfig, sendRequest } from "./utils";
2
+ import { type IServiceConfig, sendRequest } from "./utils";
3
3
 
4
4
  const SERVICES: { [key: string]: IServiceConfig } = {
5
5
  SCHEMAS_SELECT_ALL: {
@@ -7,12 +7,22 @@ const SERVICES: { [key: string]: IServiceConfig } = {
7
7
  endpoint: "/schemas/select/all",
8
8
  method: "GET",
9
9
  },
10
+ SCHEMAS: {
11
+ ...template,
12
+ endpoint: "/schemas",
13
+ method: "GET",
14
+ },
10
15
  };
11
16
 
12
17
  const getSchemasSelectAll = async () => {
13
18
  return sendRequest(SERVICES.SCHEMAS_SELECT_ALL);
14
19
  };
15
20
 
21
+ const getSchemas = async () => {
22
+ return sendRequest(SERVICES.SCHEMAS);
23
+ };
24
+
16
25
  export default {
17
26
  getSchemasSelectAll,
27
+ getSchemas,
18
28
  };