@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.
- package/config/griddo-config/index.js +1 -0
- package/package.json +2 -2
- package/src/Style/index.tsx +10 -8
- package/src/__tests__/components/ConfigPanel/ConfigPanel.test.tsx +10 -8
- package/src/__tests__/components/ConfigPanel/Form/ConnectedField/PageConnectedField/PageConnectedField.test.tsx +86 -8
- package/src/__tests__/components/SideModal/SideModal.test.tsx +64 -0
- package/src/__tests__/hooks/useSchemas.test.tsx +224 -0
- package/src/__tests__/services/SchemasService.test.ts +135 -0
- package/src/api/schemas.tsx +11 -1
- package/src/components/ConfigPanel/GlobalPageForm/index.tsx +11 -17
- package/src/components/Fields/Wysiwyg/helpers.tsx +14 -4
- package/src/components/Loader/components/Dots.js +4 -5
- package/src/components/PageFinder/index.tsx +15 -9
- package/src/components/ResizePanel/index.tsx +13 -3
- package/src/components/ResizePanel/style.tsx +2 -9
- package/src/containers/App/actions.tsx +96 -24
- package/src/containers/App/constants.tsx +7 -0
- package/src/containers/App/interfaces.tsx +26 -8
- package/src/containers/App/reducer.tsx +24 -9
- package/src/containers/Sites/actions.tsx +49 -49
- package/src/forms/editor.tsx +4 -3
- package/src/helpers/index.tsx +76 -94
- package/src/helpers/schemas.tsx +144 -36
- package/src/helpers/structuredData.tsx +36 -7
- package/src/helpers/themes.tsx +26 -8
- package/src/hooks/index.tsx +5 -0
- package/src/hooks/useSchemas.ts +151 -0
- package/src/locales/en-US.ts +1 -0
- package/src/locales/es-ES.ts +1 -0
- package/src/modules/Analytics/GroupPanel/index.tsx +9 -6
- package/src/modules/Analytics/GroupPanel/utils.tsx +12 -28
- package/src/modules/Content/PageItem/index.tsx +33 -36
- package/src/modules/Content/index.tsx +34 -30
- package/src/modules/Content/utils.tsx +16 -12
- package/src/modules/Forms/FormEditor/index.tsx +13 -14
- package/src/modules/FramePreview/index.tsx +8 -8
- package/src/modules/GlobalEditor/index.tsx +57 -42
- package/src/modules/MediaGallery/ImageModal/index.tsx +15 -9
- package/src/modules/MediaGallery/ImageModal/style.tsx +16 -1
- package/src/modules/PublicPreview/index.tsx +4 -3
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +4 -5
- package/src/modules/Settings/Globals/index.tsx +10 -11
- package/src/modules/Sites/index.tsx +13 -5
- package/src/modules/StructuredData/Form/index.tsx +25 -29
- package/src/modules/StructuredData/StructuredDataList/OptionTable/index.tsx +15 -6
- package/src/modules/StructuredData/StructuredDataList/index.tsx +22 -14
- package/src/modules/StructuredData/StructuredDataList/utils.tsx +12 -11
- package/src/schemas/index.tsx +5 -4
- package/src/schemas/pages/Page.ts +308 -0
- package/src/schemas/pages/index.ts +9 -0
- package/src/services/SchemasService.ts +240 -0
- package/src/services/index.ts +9 -0
- package/src/types/index.tsx +48 -39
- package/tsconfig.paths.json +1 -0
- package/src/schemas/pages/Page.tsx +0 -301
- package/src/schemas/pages/index.tsx +0 -5
- /package/src/schemas/pages/{FormPage.tsx → FormPage.ts} +0 -0
- /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.
|
|
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": "
|
|
220
|
+
"gitHead": "4d88c4e8c6c325193a737ee2822c55b9659986ae"
|
|
221
221
|
}
|
package/src/Style/index.tsx
CHANGED
|
@@ -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
|
-
|
|
2
|
+
|
|
6
3
|
import { normalize } from "polished";
|
|
7
|
-
import
|
|
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
|
-
|
|
29
|
-
|
|
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
|
-
|
|
178
|
-
|
|
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
|
+
}
|
package/src/api/schemas.tsx
CHANGED
|
@@ -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
|
};
|