@plone/volto 19.0.0-alpha.0 → 19.0.0-alpha.2
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/.eslintignore +1 -0
- package/.eslintrc +2 -0
- package/CHANGELOG.md +63 -2
- package/locales/ca/LC_MESSAGES/volto.po +15 -0
- package/locales/ca.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +15 -0
- package/locales/de.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +15 -0
- package/locales/en.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +15 -0
- package/locales/es.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +15 -0
- package/locales/eu.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +15 -0
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +15 -0
- package/locales/fr.json +1 -1
- package/locales/hi/LC_MESSAGES/volto.po +15 -0
- package/locales/hi.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +15 -0
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +15 -0
- package/locales/ja.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +15 -0
- package/locales/nl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +15 -0
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +15 -0
- package/locales/pt_BR.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +15 -0
- package/locales/ro.json +1 -1
- package/locales/ru/LC_MESSAGES/volto.po +15 -0
- package/locales/ru.json +1 -1
- package/locales/volto.pot +15 -0
- package/locales/zh_CN/LC_MESSAGES/volto.po +15 -0
- package/locales/zh_CN.json +1 -1
- package/package.json +15 -8
- package/src/actions/actions/actions.test.js +3 -3
- package/src/actions/addons/addons.test.js +15 -12
- package/src/actions/aliases/aliases.test.js +1 -1
- package/src/actions/querystring/querystring.test.js +2 -2
- package/src/actions/types/types.test.js +1 -1
- package/src/components/manage/Actions/Actions.test.jsx +5 -1
- package/src/components/manage/Add/Add.jsx +22 -20
- package/src/components/manage/Add/Add.test.jsx +6 -3
- package/src/components/manage/Aliases/Aliases.test.jsx +7 -7
- package/src/components/manage/Blocks/Block/BlocksForm.jsx +1 -0
- package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +48 -16
- package/src/components/manage/Blocks/Block/Edit.jsx +2 -1
- package/src/components/manage/Blocks/Block/Settings.test.jsx +5 -1
- package/src/components/manage/Blocks/Block/StyleWrapper.jsx +11 -3
- package/src/components/manage/Blocks/Description/View.test.jsx +1 -1
- package/src/components/manage/Blocks/HTML/Edit.test.jsx +12 -5
- package/src/components/manage/Blocks/HTML/View.test.jsx +1 -1
- package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +6 -2
- package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +8 -1
- package/src/components/manage/Blocks/Listing/View.test.jsx +3 -1
- package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +5 -1
- package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +13 -7
- package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +12 -6
- package/src/components/manage/Blocks/Title/Edit.jsx +8 -2
- package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.test.jsx +11 -1
- package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +5 -1
- package/src/components/manage/ConditionalLink/ConditionalLink.test.tsx +109 -0
- package/src/components/manage/ConditionalLink/ConditionalLink.tsx +36 -0
- package/src/components/manage/Contents/Contents.test.jsx +29 -13
- package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +5 -1
- package/src/components/manage/Contents/ContentsRenameModal.test.jsx +5 -1
- package/src/components/manage/Contents/ContentsTagsModal.test.jsx +5 -1
- package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +5 -1
- package/src/components/manage/Contents/__mocks__/index.tsx +16 -0
- package/src/components/manage/Contents/__mocks__/index.vitest.tsx +5 -0
- package/src/components/manage/Controlpanels/AddonsControlpanel.test.jsx +28 -3
- package/src/components/manage/Controlpanels/Aliases.test.jsx +35 -3
- package/src/components/manage/Controlpanels/ContentType.test.jsx +29 -3
- package/src/components/manage/Controlpanels/ContentTypeLayout.test.jsx +4 -2
- package/src/components/manage/Controlpanels/ContentTypes.test.jsx +25 -2
- package/src/components/manage/Controlpanels/Controlpanel.test.jsx +37 -6
- package/src/components/manage/Controlpanels/Controlpanels.test.jsx +47 -3
- package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.test.jsx +15 -9
- package/src/components/manage/Controlpanels/ModerateComments.test.jsx +31 -5
- package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +13 -4
- package/src/components/manage/Controlpanels/Rules/ConfigureRule.test.jsx +9 -5
- package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +12 -4
- package/src/components/manage/Controlpanels/Rules/Rules.test.jsx +7 -3
- package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +33 -4
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +3 -1
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +15 -9
- package/src/components/manage/Delete/Delete.test.jsx +45 -4
- package/src/components/manage/Diff/Diff.test.jsx +15 -6
- package/src/components/manage/Diff/DiffField.test.jsx +12 -6
- package/src/components/manage/Display/Display.test.jsx +17 -6
- package/src/components/manage/Edit/Edit.test.jsx +11 -3
- package/src/components/manage/Form/BlockDataForm.test.jsx +5 -1
- package/src/components/manage/Form/Form.jsx +32 -0
- package/src/components/manage/Form/Form.test.jsx +27 -19
- package/src/components/manage/Form/InlineForm.test.jsx +5 -1
- package/src/components/manage/Form/ModalForm.test.jsx +5 -1
- package/src/components/manage/Form/__mocks__/index.tsx +17 -0
- package/src/components/manage/Form/__mocks__/index.vitest.tsx +73 -0
- package/src/components/manage/History/History.test.jsx +3 -1
- package/src/components/manage/LinksToItem/LinksToItem.test.jsx +6 -4
- package/src/components/manage/MaybeWrap/MaybeWrap.tsx +15 -0
- package/src/components/manage/Multilingual/ManageTranslations.test.jsx +3 -2
- package/src/components/manage/Preferences/ChangePassword.test.jsx +9 -2
- package/src/components/manage/Preferences/PersonalInformation.test.jsx +3 -1
- package/src/components/manage/Preferences/PersonalPreferences.test.jsx +20 -7
- package/src/components/manage/Rules/Rules.test.jsx +6 -3
- package/src/components/manage/Sharing/Sharing.test.jsx +3 -1
- package/src/components/manage/Sidebar/ObjectBrowserNav.test.jsx +3 -3
- package/src/components/manage/Toolbar/More.test.jsx +6 -7
- package/src/components/manage/UniversalLink/UniversalLink.test.jsx +196 -14
- package/src/components/manage/UniversalLink/UniversalLink.tsx +214 -0
- package/src/components/manage/Widgets/ArrayWidget.test.jsx +22 -5
- package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +12 -5
- package/src/components/manage/Widgets/DatetimeWidget.test.jsx +21 -6
- package/src/components/manage/Widgets/ImageWidget.jsx +5 -2
- package/src/components/manage/Widgets/NumberWidget.test.jsx +8 -7
- package/src/components/manage/Widgets/ObjectListWidget.jsx +11 -1
- package/src/components/manage/Widgets/ObjectListWidget.test.jsx +18 -8
- package/src/components/manage/Widgets/ObjectWidget.test.jsx +5 -1
- package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +12 -5
- package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +12 -6
- package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +43 -41
- package/src/components/manage/Widgets/SchemaWidget.test.jsx +12 -5
- package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +12 -5
- package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +12 -6
- package/src/components/manage/Widgets/SelectWidget.jsx +3 -1
- package/src/components/manage/Widgets/SelectWidget.test.jsx +12 -6
- package/src/components/manage/Widgets/TimeWidget.test.jsx +13 -5
- package/src/components/manage/Widgets/TokenWidget.test.jsx +12 -6
- package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +18 -9
- package/src/components/manage/Widgets/__mocks__/index.tsx +16 -0
- package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +41 -0
- package/src/components/manage/Workflow/Workflow.test.jsx +17 -7
- package/src/components/theme/App/App.test.jsx +21 -17
- package/src/components/theme/AppExtras/AppExtras.test.jsx +6 -6
- package/src/components/theme/Comments/CommentEditModal.test.jsx +5 -1
- package/src/components/theme/Comments/Comments.test.jsx +29 -12
- package/src/components/theme/ContactForm/ContactForm.test.jsx +8 -4
- package/src/components/theme/Header/Header.test.jsx +19 -13
- package/src/components/theme/Logout/Logout.test.jsx +1 -1
- package/src/components/theme/PasswordReset/PasswordReset.test.jsx +10 -1
- package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +5 -1
- package/src/components/theme/Register/Register.test.jsx +5 -1
- package/src/components/theme/Search/Search.test.jsx +6 -4
- package/src/components/theme/TsTest/TsTest.test.tsx +0 -1
- package/src/components/theme/View/EventDatesInfo.test.jsx +12 -5
- package/src/components/theme/View/EventView.test.jsx +12 -5
- package/src/components/theme/View/ListingView.test.jsx +2 -0
- package/src/components/theme/View/SummaryView.test.jsx +10 -0
- package/src/components/theme/View/TabularView.test.jsx +1 -0
- package/src/components/theme/View/View.test.jsx +42 -23
- package/src/helpers/Api/Api.plone.rest.test.js +11 -9
- package/src/helpers/Api/Api.test.js +11 -14
- package/src/helpers/AsyncConnect/AsyncConnect.test.jsx +145 -189
- package/src/helpers/AuthToken/AuthToken.test.js +60 -22
- package/src/helpers/Blocks/Blocks.test.js +1 -1
- package/src/helpers/Html/Html.test.jsx +32 -28
- package/src/helpers/Loadable/__mocks__/Loadable.jsx +16 -1
- package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +39 -0
- package/src/helpers/Utils/withSaveAsDraft.jsx +241 -0
- package/src/middleware/Api.test.js +47 -0
- package/src/middleware/api.js +1 -1
- package/src/middleware/storeProtectLoadUtils.test.js +90 -78
- package/test-setup-globals-vitest.js +46 -0
- package/theme/themes/pastanaga/collections/table.overrides +9 -0
- package/theme/themes/pastanaga/extras/main.less +15 -0
- package/tsconfig.declarations.json +12 -1
- package/tsconfig.json +2 -1
- package/types/components/manage/ConditionalLink/ConditionalLink.d.ts +11 -15
- package/types/components/manage/Contents/__mocks__/index.vitest.d.ts +2 -0
- package/types/components/manage/Form/__mocks__/index.vitest.d.ts +8 -0
- package/types/components/manage/MaybeWrap/MaybeWrap.d.ts +7 -5
- package/types/components/manage/UniversalLink/UniversalLink.d.ts +54 -20
- package/types/components/manage/Widgets/__mocks__/index.vitest.d.ts +33 -0
- package/types/helpers/Loadable/__mocks__/Loadable.vitest.d.ts +3 -0
- package/types/helpers/Utils/withSaveAsDraft.d.ts +1 -0
- package/types/react-router-hash-link.d.ts +12 -0
- package/types/routes.d.ts +4 -0
- package/types/server.d.ts +1 -1
- package/vite-plugins/svg.mjs +81 -0
- package/vitest.config.mjs +77 -0
- package/src/components/manage/ConditionalLink/ConditionalLink.jsx +0 -27
- package/src/components/manage/ConditionalLink/ConditionalLink.test.jsx +0 -30
- package/src/components/manage/MaybeWrap/MaybeWrap.jsx +0 -9
- package/src/components/manage/UniversalLink/UniversalLink.jsx +0 -154
- package/src/components/manage/Widgets/FileWidget.test.jsx +0 -91
|
@@ -7,8 +7,14 @@ import UndoControlpanel from './UndoControlpanel';
|
|
|
7
7
|
|
|
8
8
|
const mockStore = configureStore();
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
vi.mock('@plone/volto/components/manage/Form', async () => {
|
|
11
|
+
return await import(
|
|
12
|
+
'@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
vi.mock('../../Toolbar/Toolbar', () => ({
|
|
16
|
+
default: vi.fn(() => <div id="Portal" />),
|
|
17
|
+
}));
|
|
12
18
|
|
|
13
19
|
describe('UndoControlpanel', () => {
|
|
14
20
|
it('renders undo controlpanel component', () => {
|
|
@@ -81,11 +87,34 @@ describe('UndoControlpanel', () => {
|
|
|
81
87
|
locale: 'en',
|
|
82
88
|
messages: {},
|
|
83
89
|
},
|
|
90
|
+
actions: {
|
|
91
|
+
actions: {},
|
|
92
|
+
},
|
|
93
|
+
userSession: {
|
|
94
|
+
token: null,
|
|
95
|
+
},
|
|
96
|
+
content: {
|
|
97
|
+
data: {},
|
|
98
|
+
get: {
|
|
99
|
+
loading: false,
|
|
100
|
+
loaded: true,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
types: {
|
|
104
|
+
types: [],
|
|
105
|
+
get: {
|
|
106
|
+
loading: false,
|
|
107
|
+
loaded: true,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
84
110
|
});
|
|
111
|
+
store.dispatch = vi.fn(() => Promise.resolve());
|
|
85
112
|
const { container } = render(
|
|
86
113
|
<Provider store={store}>
|
|
87
|
-
<
|
|
88
|
-
|
|
114
|
+
<div>
|
|
115
|
+
<UndoControlpanel location={{ pathname: '/blog' }} />
|
|
116
|
+
<div id="toolbar"></div>
|
|
117
|
+
</div>
|
|
89
118
|
</Provider>,
|
|
90
119
|
);
|
|
91
120
|
|
|
@@ -7,7 +7,9 @@ import { MemoryRouter } from 'react-router-dom';
|
|
|
7
7
|
import UserGroupMembershipControlPanel from './UserGroupMembershipControlPanel';
|
|
8
8
|
|
|
9
9
|
const mockStore = configureStore();
|
|
10
|
-
|
|
10
|
+
vi.mock('../../Toolbar/Toolbar', () => ({
|
|
11
|
+
default: vi.fn(() => <div id="Portal" />),
|
|
12
|
+
}));
|
|
11
13
|
|
|
12
14
|
describe('UserGroupMembershipControlPanel', () => {
|
|
13
15
|
it('renders a user group membership control component', () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { render } from '@testing-library/react';
|
|
2
|
+
import { render, act } from '@testing-library/react';
|
|
3
3
|
import configureStore from 'redux-mock-store';
|
|
4
4
|
import { Provider } from 'react-intl-redux';
|
|
5
5
|
import jwt from 'jsonwebtoken';
|
|
@@ -7,10 +7,12 @@ import jwt from 'jsonwebtoken';
|
|
|
7
7
|
import UsersControlpanel from './UsersControlpanel';
|
|
8
8
|
|
|
9
9
|
const mockStore = configureStore();
|
|
10
|
-
|
|
10
|
+
vi.mock('../../Toolbar/Toolbar', () => ({
|
|
11
|
+
default: vi.fn(() => <div id="Portal" />),
|
|
12
|
+
}));
|
|
11
13
|
|
|
12
14
|
describe('UsersControlpanel', () => {
|
|
13
|
-
it('renders a user control component', () => {
|
|
15
|
+
it('renders a user control component', async () => {
|
|
14
16
|
const store = mockStore({
|
|
15
17
|
userSession: {
|
|
16
18
|
token: jwt.sign({ sub: 'john' }, 'secret'),
|
|
@@ -36,12 +38,16 @@ describe('UsersControlpanel', () => {
|
|
|
36
38
|
messages: {},
|
|
37
39
|
},
|
|
38
40
|
});
|
|
39
|
-
const { container } =
|
|
40
|
-
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
const { container } = await act(async () => {
|
|
42
|
+
return render(
|
|
43
|
+
<Provider store={store}>
|
|
44
|
+
<>
|
|
45
|
+
<UsersControlpanel location={{ pathname: '/blog' }} />
|
|
46
|
+
<div id="toolbar"></div>
|
|
47
|
+
</>
|
|
48
|
+
</Provider>,
|
|
49
|
+
);
|
|
50
|
+
});
|
|
45
51
|
|
|
46
52
|
expect(container).toMatchSnapshot();
|
|
47
53
|
});
|
|
@@ -3,12 +3,13 @@ import { render } from '@testing-library/react';
|
|
|
3
3
|
import configureStore from 'redux-mock-store';
|
|
4
4
|
import { Provider } from 'react-intl-redux';
|
|
5
5
|
import { MemoryRouter } from 'react-router-dom';
|
|
6
|
-
|
|
7
6
|
import Delete from './Delete';
|
|
8
7
|
|
|
9
8
|
const mockStore = configureStore();
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
vi.mock('../../Toolbar/Toolbar', () => ({
|
|
11
|
+
default: vi.fn(() => <div id="Portal" />),
|
|
12
|
+
}));
|
|
12
13
|
|
|
13
14
|
describe('Delete', () => {
|
|
14
15
|
it('renders an empty delete component', () => {
|
|
@@ -19,16 +20,36 @@ describe('Delete', () => {
|
|
|
19
20
|
loading: false,
|
|
20
21
|
loaded: true,
|
|
21
22
|
},
|
|
23
|
+
get: {
|
|
24
|
+
loading: false,
|
|
25
|
+
loaded: true,
|
|
26
|
+
},
|
|
22
27
|
},
|
|
23
28
|
intl: {
|
|
24
29
|
locale: 'en',
|
|
25
30
|
messages: {},
|
|
26
31
|
},
|
|
32
|
+
actions: {
|
|
33
|
+
actions: {},
|
|
34
|
+
},
|
|
35
|
+
userSession: {
|
|
36
|
+
token: null,
|
|
37
|
+
},
|
|
38
|
+
types: {
|
|
39
|
+
types: [],
|
|
40
|
+
get: {
|
|
41
|
+
loading: false,
|
|
42
|
+
loaded: true,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
27
45
|
});
|
|
46
|
+
|
|
47
|
+
store.dispatch = vi.fn(() => Promise.resolve());
|
|
48
|
+
|
|
28
49
|
const { container } = render(
|
|
29
50
|
<Provider store={store}>
|
|
30
51
|
<MemoryRouter>
|
|
31
|
-
<Delete location={{ pathname: '/blog', search:
|
|
52
|
+
<Delete location={{ pathname: '/blog', search: '' }} />
|
|
32
53
|
<div id="toolbar"></div>
|
|
33
54
|
</MemoryRouter>
|
|
34
55
|
</Provider>,
|
|
@@ -47,16 +68,36 @@ describe('Delete', () => {
|
|
|
47
68
|
loading: false,
|
|
48
69
|
loaded: true,
|
|
49
70
|
},
|
|
71
|
+
get: {
|
|
72
|
+
loading: false,
|
|
73
|
+
loaded: true,
|
|
74
|
+
},
|
|
50
75
|
},
|
|
51
76
|
intl: {
|
|
52
77
|
locale: 'en',
|
|
53
78
|
messages: {},
|
|
54
79
|
},
|
|
80
|
+
actions: {
|
|
81
|
+
actions: {},
|
|
82
|
+
},
|
|
83
|
+
userSession: {
|
|
84
|
+
token: null,
|
|
85
|
+
},
|
|
86
|
+
types: {
|
|
87
|
+
types: [],
|
|
88
|
+
get: {
|
|
89
|
+
loading: false,
|
|
90
|
+
loaded: true,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
55
93
|
});
|
|
94
|
+
|
|
95
|
+
store.dispatch = vi.fn(() => Promise.resolve());
|
|
96
|
+
|
|
56
97
|
const { container } = render(
|
|
57
98
|
<Provider store={store}>
|
|
58
99
|
<MemoryRouter>
|
|
59
|
-
<Delete location={{ pathname: '/blog', search:
|
|
100
|
+
<Delete location={{ pathname: '/blog', search: '' }} />
|
|
60
101
|
<div id="toolbar"></div>
|
|
61
102
|
</MemoryRouter>
|
|
62
103
|
</Provider>,
|
|
@@ -8,13 +8,22 @@ import Diff from './Diff';
|
|
|
8
8
|
|
|
9
9
|
const mockStore = configureStore();
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
vi.mock('../Toolbar/Toolbar', () => ({
|
|
12
|
+
default: vi.fn(() => <div id="Portal" />),
|
|
13
|
+
}));
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
);
|
|
15
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
|
|
16
|
+
return await import(
|
|
17
|
+
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
beforeAll(async () => {
|
|
22
|
+
const { __setLoadables } = await import(
|
|
23
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
24
|
+
);
|
|
25
|
+
await __setLoadables();
|
|
26
|
+
});
|
|
18
27
|
|
|
19
28
|
describe('Diff', () => {
|
|
20
29
|
it('renders a diff component', async () => {
|
|
@@ -2,14 +2,20 @@ import React from 'react';
|
|
|
2
2
|
import configureStore from 'redux-mock-store';
|
|
3
3
|
import { Provider } from 'react-intl-redux';
|
|
4
4
|
import { waitFor, render, screen } from '@testing-library/react';
|
|
5
|
-
|
|
6
5
|
import DiffField from './DiffField';
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
);
|
|
7
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
|
|
8
|
+
return await import(
|
|
9
|
+
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
10
|
+
);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
beforeAll(async () => {
|
|
14
|
+
const { __setLoadables } = await import(
|
|
15
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
16
|
+
);
|
|
17
|
+
await __setLoadables();
|
|
18
|
+
});
|
|
13
19
|
|
|
14
20
|
const mockStore = configureStore();
|
|
15
21
|
|
|
@@ -8,12 +8,23 @@ import Display from './Display';
|
|
|
8
8
|
|
|
9
9
|
const mockStore = configureStore();
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
)
|
|
11
|
+
vi.mock('@plone/volto/components/manage/Widgets', async () => {
|
|
12
|
+
return await import(
|
|
13
|
+
'@plone/volto/components/manage/Widgets/__mocks__/index.vitest.tsx'
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
|
|
17
|
+
return await import(
|
|
18
|
+
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
beforeAll(async () => {
|
|
23
|
+
const { __setLoadables } = await import(
|
|
24
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
25
|
+
);
|
|
26
|
+
await __setLoadables();
|
|
27
|
+
});
|
|
17
28
|
|
|
18
29
|
beforeEach(() => {
|
|
19
30
|
config.views.layoutViewsNamesMapping = {
|
|
@@ -8,9 +8,17 @@ import { __test__ as Edit } from './Edit';
|
|
|
8
8
|
|
|
9
9
|
const mockStore = configureStore();
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
vi.mock('@plone/volto/components/manage/Form', async () => {
|
|
12
|
+
return await import(
|
|
13
|
+
'@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
vi.mock('../Toolbar/Toolbar', () => ({
|
|
17
|
+
default: vi.fn(() => <div id="Portal" />),
|
|
18
|
+
}));
|
|
19
|
+
vi.mock('../Sidebar/Sidebar', () => ({
|
|
20
|
+
default: vi.fn(() => <div id="Sidebar" />),
|
|
21
|
+
}));
|
|
14
22
|
|
|
15
23
|
describe('Edit', () => {
|
|
16
24
|
it('renders an empty edit component', () => {
|
|
@@ -5,7 +5,11 @@ import configureStore from 'redux-mock-store';
|
|
|
5
5
|
import config from '@plone/volto/registry';
|
|
6
6
|
import { Provider } from 'react-intl-redux';
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
vi.mock('@plone/volto/components/manage/Form', async () => {
|
|
9
|
+
return await import(
|
|
10
|
+
'@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
|
|
11
|
+
);
|
|
12
|
+
});
|
|
9
13
|
|
|
10
14
|
const mockStore = configureStore();
|
|
11
15
|
|
|
@@ -9,6 +9,7 @@ import { Field, BlocksForm } from '@plone/volto/components/manage/Form';
|
|
|
9
9
|
import BlocksToolbar from '@plone/volto/components/manage/Form/BlocksToolbar';
|
|
10
10
|
import UndoToolbar from '@plone/volto/components/manage/Form/UndoToolbar';
|
|
11
11
|
import { difference } from '@plone/volto/helpers/Utils/Utils';
|
|
12
|
+
import withSaveAsDraft from '@plone/volto/helpers/Utils/withSaveAsDraft';
|
|
12
13
|
import FormValidation from '@plone/volto/helpers/FormValidation/FormValidation';
|
|
13
14
|
import {
|
|
14
15
|
getBlocksFieldname,
|
|
@@ -265,6 +266,18 @@ class Form extends Component {
|
|
|
265
266
|
this.onBlurField = this.onBlurField.bind(this);
|
|
266
267
|
this.onClickInput = this.onClickInput.bind(this);
|
|
267
268
|
this.onToggleMetadataFieldset = this.onToggleMetadataFieldset.bind(this);
|
|
269
|
+
this.updateFormDataWithSaved = this.updateFormDataWithSaved.bind(this);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Function sent as callback to saveAsDraft when user
|
|
274
|
+
* choses to load local data
|
|
275
|
+
* @param {Object} savedFormData
|
|
276
|
+
*/
|
|
277
|
+
updateFormDataWithSaved(savedFormData) {
|
|
278
|
+
if (savedFormData) {
|
|
279
|
+
this.setState({ formData: savedFormData });
|
|
280
|
+
}
|
|
268
281
|
}
|
|
269
282
|
|
|
270
283
|
/**
|
|
@@ -278,6 +291,12 @@ class Form extends Component {
|
|
|
278
291
|
let errors = {};
|
|
279
292
|
let activeIndex = 0;
|
|
280
293
|
|
|
294
|
+
if (!prevProps.schema && this.props.schema) {
|
|
295
|
+
this.props.checkSavedDraft(
|
|
296
|
+
this.state.formData,
|
|
297
|
+
this.updateFormDataWithSaved,
|
|
298
|
+
);
|
|
299
|
+
}
|
|
281
300
|
if (!this.props.isFormSelected && prevProps.isFormSelected) {
|
|
282
301
|
this.props.setUIState({
|
|
283
302
|
selected: null,
|
|
@@ -303,6 +322,10 @@ class Form extends Component {
|
|
|
303
322
|
this.props.onChangeFormData(this.state.formData);
|
|
304
323
|
}
|
|
305
324
|
}
|
|
325
|
+
// on each formData update it will save the form to the localStorage
|
|
326
|
+
if (!isEqual(prevState?.formData, this.state.formData)) {
|
|
327
|
+
this.props.onSaveDraft(this.state.formData);
|
|
328
|
+
}
|
|
306
329
|
if (
|
|
307
330
|
this.props.global &&
|
|
308
331
|
!isEqual(this.props.globalData, prevProps.globalData)
|
|
@@ -395,6 +418,13 @@ class Form extends Component {
|
|
|
395
418
|
*/
|
|
396
419
|
componentDidMount() {
|
|
397
420
|
this.setState({ isClient: true });
|
|
421
|
+
if (this.props.schema) {
|
|
422
|
+
this.props.checkSavedDraft(
|
|
423
|
+
this.state.formData,
|
|
424
|
+
this.updateFormDataWithSaved,
|
|
425
|
+
);
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
398
428
|
}
|
|
399
429
|
|
|
400
430
|
/**
|
|
@@ -653,6 +683,7 @@ class Form extends Component {
|
|
|
653
683
|
this.props.setFormData(this.props.formData);
|
|
654
684
|
}
|
|
655
685
|
}
|
|
686
|
+
this.props.onCancelDraft();
|
|
656
687
|
}
|
|
657
688
|
}
|
|
658
689
|
|
|
@@ -1136,4 +1167,5 @@ export default compose(
|
|
|
1136
1167
|
null,
|
|
1137
1168
|
{ forwardRef: true },
|
|
1138
1169
|
),
|
|
1170
|
+
withSaveAsDraft({ forwardRef: true }),
|
|
1139
1171
|
)(FormIntl);
|
|
@@ -2,14 +2,18 @@ import React from 'react';
|
|
|
2
2
|
import renderer from 'react-test-renderer';
|
|
3
3
|
import configureStore from 'redux-mock-store';
|
|
4
4
|
import { Provider } from 'react-intl-redux';
|
|
5
|
-
|
|
5
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
6
6
|
import Form from './Form';
|
|
7
7
|
|
|
8
8
|
const mockStore = configureStore();
|
|
9
9
|
const errorMessage =
|
|
10
10
|
"[{'message': 'The specified email is not valid.', 'field': 'contact_email', 'error': 'ValidationError'}";
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
vi.mock('@plone/volto/components/manage/Form', async () => {
|
|
13
|
+
return await import(
|
|
14
|
+
'@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
|
|
15
|
+
);
|
|
16
|
+
});
|
|
13
17
|
|
|
14
18
|
describe('Form', () => {
|
|
15
19
|
it('renders a form component', () => {
|
|
@@ -26,26 +30,30 @@ describe('Form', () => {
|
|
|
26
30
|
},
|
|
27
31
|
},
|
|
28
32
|
});
|
|
33
|
+
const route = '/some-route';
|
|
29
34
|
const component = renderer.create(
|
|
30
35
|
<Provider store={store}>
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
<MemoryRouter initialEntries={[route]}>
|
|
37
|
+
<Form
|
|
38
|
+
schema={{
|
|
39
|
+
fieldsets: [
|
|
40
|
+
{
|
|
41
|
+
id: 'default',
|
|
42
|
+
title: 'Default',
|
|
43
|
+
fields: ['title'],
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
properties: {
|
|
47
|
+
title: {},
|
|
38
48
|
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
onCancel={() => {}}
|
|
48
|
-
/>
|
|
49
|
+
required: [],
|
|
50
|
+
}}
|
|
51
|
+
requestError={errorMessage}
|
|
52
|
+
onSubmit={() => {}}
|
|
53
|
+
onCancel={() => {}}
|
|
54
|
+
/>
|
|
55
|
+
</MemoryRouter>
|
|
56
|
+
,
|
|
49
57
|
</Provider>,
|
|
50
58
|
);
|
|
51
59
|
const json = component.toJSON();
|
|
@@ -6,7 +6,11 @@ import config from '@plone/volto/registry';
|
|
|
6
6
|
|
|
7
7
|
import InlineForm from './InlineForm';
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
vi.mock('@plone/volto/components/manage/Form', async () => {
|
|
10
|
+
return await import(
|
|
11
|
+
'@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
|
|
12
|
+
);
|
|
13
|
+
});
|
|
10
14
|
|
|
11
15
|
const mockStore = configureStore();
|
|
12
16
|
|
|
@@ -8,7 +8,11 @@ import ModalForm from './ModalForm';
|
|
|
8
8
|
|
|
9
9
|
const mockStore = configureStore();
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
vi.mock('@plone/volto/components/manage/Form', async () => {
|
|
12
|
+
return await import(
|
|
13
|
+
'@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
|
|
14
|
+
);
|
|
15
|
+
});
|
|
12
16
|
|
|
13
17
|
describe('ModalForm', () => {
|
|
14
18
|
it('renders a modal form component', () => {
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/* TODO: When the Volto Team removes Jest configuration support from Volto core, update this file with the Vitest version of the mock.
|
|
2
|
+
Then, in the tests, we need to replace:
|
|
3
|
+
|
|
4
|
+
vi.mock('@plone/volto/components/manage/Form', async () => {
|
|
5
|
+
return await import(
|
|
6
|
+
'@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
|
|
7
|
+
);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
with the following:
|
|
12
|
+
|
|
13
|
+
vi.mock('@plone/volto/components/manage/Form');
|
|
14
|
+
|
|
15
|
+
Finally, remove this comment.
|
|
16
|
+
*/
|
|
17
|
+
|
|
1
18
|
import type { JSONSchema } from '@plone/types';
|
|
2
19
|
import type { Ref } from 'react';
|
|
3
20
|
const { forwardRef } = jest.requireActual('react');
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { JSONSchema } from '@plone/types';
|
|
2
|
+
import type { Ref } from 'react';
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
|
+
|
|
5
|
+
const cleanupSchema = (schema: JSONSchema | null): JSONSchema | null => {
|
|
6
|
+
if (!schema || !schema.properties) return schema;
|
|
7
|
+
return {
|
|
8
|
+
...schema,
|
|
9
|
+
properties: Object.entries(schema.properties).reduce<Record<string, any>>(
|
|
10
|
+
(acc, [key, value]) => {
|
|
11
|
+
acc[key] = {
|
|
12
|
+
...value,
|
|
13
|
+
description:
|
|
14
|
+
typeof value.description === 'string'
|
|
15
|
+
? value.description
|
|
16
|
+
: undefined,
|
|
17
|
+
};
|
|
18
|
+
return acc;
|
|
19
|
+
},
|
|
20
|
+
{},
|
|
21
|
+
),
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Field = vi.fn((props) => (
|
|
26
|
+
<div className="Field" id={props.id}>
|
|
27
|
+
{props.title}
|
|
28
|
+
</div>
|
|
29
|
+
));
|
|
30
|
+
|
|
31
|
+
export const InlineForm = vi.fn((props) => (
|
|
32
|
+
<div
|
|
33
|
+
id="InlineForm"
|
|
34
|
+
data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
|
|
35
|
+
/>
|
|
36
|
+
));
|
|
37
|
+
|
|
38
|
+
export const ModalForm = vi.fn((props) => (
|
|
39
|
+
<div
|
|
40
|
+
id="ModalForm"
|
|
41
|
+
data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
|
|
42
|
+
/>
|
|
43
|
+
));
|
|
44
|
+
|
|
45
|
+
export const UndoToolbar = vi.fn(() => <div id="UndoToolbar" />);
|
|
46
|
+
|
|
47
|
+
export const BlocksToolbar = vi.fn(() => <div id="BlocksToolbar" />);
|
|
48
|
+
|
|
49
|
+
export const BlockDataForm = vi.fn((props) => (
|
|
50
|
+
<div
|
|
51
|
+
id="BlockDataForm"
|
|
52
|
+
data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
|
|
53
|
+
/>
|
|
54
|
+
));
|
|
55
|
+
|
|
56
|
+
export const BlocksForm = vi.fn((props) => (
|
|
57
|
+
<div
|
|
58
|
+
id="BlocksForm"
|
|
59
|
+
data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
|
|
60
|
+
/>
|
|
61
|
+
));
|
|
62
|
+
|
|
63
|
+
const MockForm = forwardRef(
|
|
64
|
+
(props: { schema: JSONSchema | null }, ref: Ref<any>) => (
|
|
65
|
+
<div
|
|
66
|
+
id="Form"
|
|
67
|
+
data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
|
|
68
|
+
ref={ref}
|
|
69
|
+
/>
|
|
70
|
+
),
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
export const Form = vi.fn((props) => <MockForm {...props} />);
|
|
@@ -9,7 +9,9 @@ import FakeTimers from '@sinonjs/fake-timers';
|
|
|
9
9
|
import History from './History';
|
|
10
10
|
|
|
11
11
|
const mockStore = configureStore();
|
|
12
|
-
|
|
12
|
+
vi.mock('../Toolbar/Toolbar', () => ({
|
|
13
|
+
default: vi.fn(() => <div id="Portal" />),
|
|
14
|
+
}));
|
|
13
15
|
|
|
14
16
|
const FIXED_SYSTEM_TIME = '2017-04-23T15:38:00.000Z';
|
|
15
17
|
|
|
@@ -10,10 +10,12 @@ import { __test__ as LinksToItem } from './LinksToItem';
|
|
|
10
10
|
const middlewares = [thunk];
|
|
11
11
|
const mockStore = configureMockStore(middlewares);
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
vi.mock('../Toolbar/Toolbar', () => ({
|
|
14
|
+
default: vi.fn(() => <div id="Portal" />),
|
|
15
|
+
}));
|
|
16
|
+
vi.mock('../Toolbar/More', () => ({
|
|
17
|
+
default: vi.fn(() => <div className="More" />),
|
|
18
|
+
}));
|
|
17
19
|
describe('LinksToItem', () => {
|
|
18
20
|
it('renders "links and references" view', () => {
|
|
19
21
|
const store = mockStore({
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React, { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
|
|
3
|
+
type MaybeWrapProps<T extends React.ElementType> = {
|
|
4
|
+
condition: boolean;
|
|
5
|
+
as: T;
|
|
6
|
+
} & ComponentPropsWithoutRef<React.ElementType extends T ? 'div' : T>;
|
|
7
|
+
|
|
8
|
+
function MaybeWrap<T extends React.ElementType = 'div'>(
|
|
9
|
+
props: MaybeWrapProps<T>,
|
|
10
|
+
) {
|
|
11
|
+
const { as: Component = 'div', condition, ...rest } = props;
|
|
12
|
+
return condition ? <Component {...rest} /> : props.children;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default MaybeWrap;
|
|
@@ -11,8 +11,9 @@ beforeAll(() => {
|
|
|
11
11
|
config.settings.isMultilingual = true;
|
|
12
12
|
config.settings.supportedLanguages = ['de', 'es'];
|
|
13
13
|
});
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
vi.mock('../Toolbar/Toolbar', () => ({
|
|
15
|
+
default: vi.fn(() => <div id="Portal" />),
|
|
16
|
+
}));
|
|
16
17
|
|
|
17
18
|
const mockStore = configureStore();
|
|
18
19
|
|