@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
|
@@ -3,25 +3,50 @@ import { Provider } from 'react-intl-redux';
|
|
|
3
3
|
import configureStore from 'redux-mock-store';
|
|
4
4
|
import BlocksForm from './BlocksForm';
|
|
5
5
|
import { render } from '@testing-library/react';
|
|
6
|
-
|
|
7
6
|
import config from '@plone/volto/registry';
|
|
8
7
|
|
|
9
8
|
config.experimental = { addBlockButton: { enabled: false } };
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
);
|
|
10
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
|
|
11
|
+
return await import(
|
|
12
|
+
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
13
|
+
);
|
|
14
|
+
});
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
beforeAll(async () => {
|
|
17
|
+
const { __setLoadables } = await import(
|
|
18
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
19
|
+
);
|
|
20
|
+
await __setLoadables();
|
|
21
|
+
});
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
let mockSerial = 0;
|
|
24
|
+
vi.mock('uuid', () => {
|
|
20
25
|
return {
|
|
21
|
-
v4:
|
|
26
|
+
v4: vi.fn().mockImplementation(() => `id-${mockSerial++}`),
|
|
22
27
|
};
|
|
23
28
|
});
|
|
24
29
|
|
|
30
|
+
vi.mock('react-beautiful-dnd', () => ({
|
|
31
|
+
DragDropContext: ({ children }) => <div>{children}</div>,
|
|
32
|
+
Droppable: ({ children }) =>
|
|
33
|
+
children({
|
|
34
|
+
innerRef: () => {},
|
|
35
|
+
droppableProps: {},
|
|
36
|
+
placeholder: <div />,
|
|
37
|
+
}),
|
|
38
|
+
Draggable: ({ children }) =>
|
|
39
|
+
children({
|
|
40
|
+
innerRef: () => {},
|
|
41
|
+
draggableProps: {},
|
|
42
|
+
dragHandleProps: {},
|
|
43
|
+
}),
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
vi.mock('./Order/Order', () => ({
|
|
47
|
+
default: () => <div>Order Component</div>,
|
|
48
|
+
}));
|
|
49
|
+
|
|
25
50
|
const mockStore = configureStore();
|
|
26
51
|
|
|
27
52
|
test('Allow override of blocksConfig', () => {
|
|
@@ -70,10 +95,13 @@ test('Allow override of blocksConfig', () => {
|
|
|
70
95
|
|
|
71
96
|
const { container } = render(
|
|
72
97
|
<Provider store={store}>
|
|
73
|
-
<
|
|
74
|
-
|
|
98
|
+
<div>
|
|
99
|
+
<BlocksForm {...data} />
|
|
100
|
+
<div id="sidebar-order"></div>
|
|
101
|
+
</div>
|
|
75
102
|
</Provider>,
|
|
76
103
|
);
|
|
104
|
+
|
|
77
105
|
expect(container).toMatchSnapshot();
|
|
78
106
|
});
|
|
79
107
|
|
|
@@ -88,7 +116,7 @@ test('Removes invalid blocks on saving', () => {
|
|
|
88
116
|
},
|
|
89
117
|
});
|
|
90
118
|
|
|
91
|
-
const onChangeFormData =
|
|
119
|
+
const onChangeFormData = vi.fn(() => {});
|
|
92
120
|
|
|
93
121
|
const data = {
|
|
94
122
|
pathname: '/test',
|
|
@@ -126,18 +154,22 @@ test('Removes invalid blocks on saving', () => {
|
|
|
126
154
|
|
|
127
155
|
render(
|
|
128
156
|
<Provider store={store}>
|
|
129
|
-
<
|
|
130
|
-
|
|
157
|
+
<div>
|
|
158
|
+
<BlocksForm {...data} />
|
|
159
|
+
<div id="sidebar-order"></div>
|
|
160
|
+
</div>
|
|
131
161
|
</Provider>,
|
|
132
162
|
);
|
|
133
|
-
|
|
163
|
+
|
|
164
|
+
expect(onChangeFormData).toHaveBeenCalledWith({
|
|
134
165
|
blocks: {
|
|
135
166
|
a: { '@type': 'custom', text: 'a' },
|
|
136
167
|
b: { '@type': 'custom', text: 'b' },
|
|
137
168
|
},
|
|
138
169
|
blocks_layout: { items: ['a', 'b', 'MISSING-YOU-1'] },
|
|
139
170
|
});
|
|
140
|
-
|
|
171
|
+
|
|
172
|
+
expect(onChangeFormData).toHaveBeenCalledWith({
|
|
141
173
|
blocks: {
|
|
142
174
|
a: { '@type': 'custom', text: 'a' },
|
|
143
175
|
b: { '@type': 'custom', text: 'b' },
|
|
@@ -122,7 +122,7 @@ export class Edit extends Component {
|
|
|
122
122
|
*/
|
|
123
123
|
render() {
|
|
124
124
|
const { blocksConfig = config.blocks.blocksConfig } = this.props;
|
|
125
|
-
const { editable, type } = this.props;
|
|
125
|
+
const { editable, type, isContainer: parentIsContainer } = this.props;
|
|
126
126
|
|
|
127
127
|
const disableNewBlocks = this.props.data?.disableNewBlocks;
|
|
128
128
|
|
|
@@ -198,6 +198,7 @@ export class Edit extends Component {
|
|
|
198
198
|
{...this.props}
|
|
199
199
|
blockNode={this.blockNode}
|
|
200
200
|
data={this.props.data}
|
|
201
|
+
className={cx({ contained: parentIsContainer })}
|
|
201
202
|
/>
|
|
202
203
|
{this.props.manage && (
|
|
203
204
|
<SidebarPortal
|
|
@@ -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,7 +9,13 @@ import {
|
|
|
9
9
|
const StyleWrapper = (props) => {
|
|
10
10
|
let classNames,
|
|
11
11
|
style = [];
|
|
12
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
block,
|
|
14
|
+
children,
|
|
15
|
+
content,
|
|
16
|
+
data = {},
|
|
17
|
+
isContainer: parentIsContainer,
|
|
18
|
+
} = props;
|
|
13
19
|
classNames = buildStyleClassNamesFromData(data.styles);
|
|
14
20
|
|
|
15
21
|
classNames = buildStyleClassNamesExtenders({
|
|
@@ -24,14 +30,16 @@ const StyleWrapper = (props) => {
|
|
|
24
30
|
'',
|
|
25
31
|
// If we are rendering blocks inside a container, then pass also the data from the container
|
|
26
32
|
// This is needed in order to calculate properly the styles for the blocks inside the container
|
|
27
|
-
|
|
33
|
+
parentIsContainer && content.blocks ? content : {},
|
|
28
34
|
);
|
|
29
35
|
|
|
30
36
|
const rewrittenChildren = React.Children.map(children, (child) => {
|
|
31
37
|
if (React.isValidElement(child)) {
|
|
32
38
|
const childProps = {
|
|
33
39
|
...props,
|
|
34
|
-
className: cx([child.props.className, ...classNames]
|
|
40
|
+
className: cx([child.props.className, ...classNames], {
|
|
41
|
+
contained: parentIsContainer,
|
|
42
|
+
}),
|
|
35
43
|
style: { ...child.props.style, ...style },
|
|
36
44
|
};
|
|
37
45
|
return React.cloneElement(child, childProps);
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import renderer from 'react-test-renderer';
|
|
3
3
|
import View from './View';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
it('renders a view description component', () => {
|
|
6
6
|
const component = renderer.create(
|
|
7
7
|
<View properties={{ description: 'My Description' }} />,
|
|
8
8
|
);
|
|
@@ -7,11 +7,18 @@ import Edit from './Edit';
|
|
|
7
7
|
|
|
8
8
|
const mockStore = configureStore();
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
);
|
|
10
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
|
|
11
|
+
return await import(
|
|
12
|
+
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
beforeAll(async () => {
|
|
17
|
+
const { __setLoadables } = await import(
|
|
18
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
19
|
+
);
|
|
20
|
+
await __setLoadables();
|
|
21
|
+
});
|
|
15
22
|
|
|
16
23
|
test('renders an edit html block component', async () => {
|
|
17
24
|
const store = mockStore({
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import renderer from 'react-test-renderer';
|
|
3
3
|
import View from './View';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
it('renders a view html component', () => {
|
|
6
6
|
const component = renderer.create(<View data={{ html: '<h1></h1>' }} />);
|
|
7
7
|
const json = component.toJSON();
|
|
8
8
|
expect(json).toMatchSnapshot();
|
|
@@ -5,11 +5,15 @@ import { Provider } from 'react-intl-redux';
|
|
|
5
5
|
|
|
6
6
|
import ImageSidebar from './ImageSidebar';
|
|
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
|
|
|
12
|
-
|
|
16
|
+
it('renders an Image Block Sidebar component', () => {
|
|
13
17
|
const store = mockStore({
|
|
14
18
|
content: {
|
|
15
19
|
create: {},
|
|
@@ -5,7 +5,12 @@ import { Provider } from 'react-intl-redux';
|
|
|
5
5
|
|
|
6
6
|
import LeadImageSidebar from './LeadImageSidebar';
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
vi.mock('@plone/volto/components/manage/Widgets');
|
|
9
|
+
vi.mock('@plone/volto/components/manage/Widgets', async () => {
|
|
10
|
+
return await import(
|
|
11
|
+
'@plone/volto/components/manage/Widgets/__mocks__/index.vitest.tsx'
|
|
12
|
+
);
|
|
13
|
+
});
|
|
9
14
|
|
|
10
15
|
const mockStore = configureStore();
|
|
11
16
|
|
|
@@ -16,6 +21,7 @@ test('renders a Lead Image block Sidebar component', () => {
|
|
|
16
21
|
messages: {},
|
|
17
22
|
},
|
|
18
23
|
});
|
|
24
|
+
|
|
19
25
|
const component = renderer.create(
|
|
20
26
|
<Provider store={store}>
|
|
21
27
|
<LeadImageSidebar
|
|
@@ -45,6 +51,7 @@ test('renders a Lead Image block Sidebar component', () => {
|
|
|
45
51
|
/>
|
|
46
52
|
</Provider>,
|
|
47
53
|
);
|
|
54
|
+
|
|
48
55
|
const json = component.toJSON();
|
|
49
56
|
expect(json).toMatchSnapshot();
|
|
50
57
|
});
|
|
@@ -2,7 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import renderer from 'react-test-renderer';
|
|
3
3
|
import View from './View';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
vi.mock('./ListingBody', () => ({
|
|
6
|
+
default: () => <div className="theblock" />,
|
|
7
|
+
}));
|
|
6
8
|
|
|
7
9
|
test('renders a view image component for the listing block', () => {
|
|
8
10
|
const component = renderer.create(
|
|
@@ -5,7 +5,11 @@ import { Provider } from 'react-intl-redux';
|
|
|
5
5
|
|
|
6
6
|
import MapsSidebar from './MapsSidebar';
|
|
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
|
|
|
@@ -2,18 +2,24 @@ 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 DateRangeFacet from './DateRangeFacet';
|
|
7
6
|
|
|
8
7
|
const mockStore = configureStore();
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
);
|
|
9
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
|
|
10
|
+
return await import(
|
|
11
|
+
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
12
|
+
);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
const { __setLoadables } = await import(
|
|
17
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
18
|
+
);
|
|
19
|
+
await __setLoadables();
|
|
20
|
+
});
|
|
15
21
|
|
|
16
|
-
describe('
|
|
22
|
+
describe('DateRangeFacet', () => {
|
|
17
23
|
it('renders a facet component with a date range widget', async () => {
|
|
18
24
|
const store = mockStore({
|
|
19
25
|
userSession: { token: null },
|
|
@@ -2,16 +2,22 @@ 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 SelectFacet from './SelectFacet';
|
|
7
6
|
|
|
8
7
|
const mockStore = configureStore();
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
);
|
|
9
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
|
|
10
|
+
return await import(
|
|
11
|
+
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
12
|
+
);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
const { __setLoadables } = await import(
|
|
17
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
18
|
+
);
|
|
19
|
+
await __setLoadables();
|
|
20
|
+
});
|
|
15
21
|
|
|
16
22
|
describe('SelectFacet', () => {
|
|
17
23
|
it('renders a facet component with select dropdown', async () => {
|
|
@@ -77,8 +77,14 @@ export const TitleBlockEdit = (props) => {
|
|
|
77
77
|
ReactEditor.focus(editor);
|
|
78
78
|
} else {
|
|
79
79
|
// nothing is selected, move focus to end
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
// make sure that the editor is focused
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
const focused = ReactEditor.focus(editor);
|
|
83
|
+
if (!focused) {
|
|
84
|
+
ReactEditor.focus(editor);
|
|
85
|
+
Transforms.select(editor, Editor.end(editor, []));
|
|
86
|
+
}
|
|
87
|
+
}, 0);
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
90
|
}, [prevSelected, selected, editor]);
|
|
@@ -8,6 +8,12 @@ const mockStore = configureStore();
|
|
|
8
8
|
|
|
9
9
|
const data = { '@type': 'toc', variation: 'default' };
|
|
10
10
|
|
|
11
|
+
const properties = {
|
|
12
|
+
title: 'Table of Contents',
|
|
13
|
+
hide_title: false,
|
|
14
|
+
ordered: true,
|
|
15
|
+
};
|
|
16
|
+
|
|
11
17
|
const tocEntries = [
|
|
12
18
|
{
|
|
13
19
|
level: 2,
|
|
@@ -35,7 +41,11 @@ test('renders a default toc renderer component', () => {
|
|
|
35
41
|
const component = renderer.create(
|
|
36
42
|
<Provider store={store}>
|
|
37
43
|
<MemoryRouter>
|
|
38
|
-
<DefaultTocRenderer
|
|
44
|
+
<DefaultTocRenderer
|
|
45
|
+
properties={properties}
|
|
46
|
+
data={data}
|
|
47
|
+
tocEntries={tocEntries}
|
|
48
|
+
/>
|
|
39
49
|
</MemoryRouter>
|
|
40
50
|
</Provider>,
|
|
41
51
|
);
|
|
@@ -5,7 +5,11 @@ import { Provider } from 'react-intl-redux';
|
|
|
5
5
|
|
|
6
6
|
import VideoSidebar from './VideoSidebar';
|
|
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
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
4
|
+
import { Provider } from 'react-intl-redux';
|
|
5
|
+
import configureStore from 'redux-mock-store';
|
|
6
|
+
import '@testing-library/jest-dom';
|
|
7
|
+
|
|
8
|
+
import ConditionalLink from './ConditionalLink';
|
|
9
|
+
|
|
10
|
+
const mockStore = configureStore();
|
|
11
|
+
const store = mockStore({
|
|
12
|
+
userSession: {
|
|
13
|
+
token: null,
|
|
14
|
+
},
|
|
15
|
+
intl: {
|
|
16
|
+
locale: 'en',
|
|
17
|
+
messages: {},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('ConditionalLink', () => {
|
|
22
|
+
it('renders a link when condition is true', () => {
|
|
23
|
+
render(
|
|
24
|
+
<Provider store={store}>
|
|
25
|
+
<MemoryRouter>
|
|
26
|
+
<ConditionalLink to="/test" condition={true}>
|
|
27
|
+
Link Text
|
|
28
|
+
</ConditionalLink>
|
|
29
|
+
</MemoryRouter>
|
|
30
|
+
</Provider>,
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const link = screen.getByText('Link Text');
|
|
34
|
+
expect(link.tagName).toBe('A');
|
|
35
|
+
expect(link).toHaveAttribute('href', '/test');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('renders a link when condition is true', () => {
|
|
39
|
+
render(
|
|
40
|
+
<Provider store={store}>
|
|
41
|
+
<MemoryRouter>
|
|
42
|
+
<ConditionalLink href="/test" condition={true}>
|
|
43
|
+
Link Text
|
|
44
|
+
</ConditionalLink>
|
|
45
|
+
</MemoryRouter>
|
|
46
|
+
</Provider>,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const link = screen.getByText('Link Text');
|
|
50
|
+
expect(link.tagName).toBe('A');
|
|
51
|
+
expect(link).toHaveAttribute('href', '/test');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('renders a span when condition is false', () => {
|
|
55
|
+
render(
|
|
56
|
+
<Provider store={store}>
|
|
57
|
+
<MemoryRouter>
|
|
58
|
+
<ConditionalLink to="/test" condition={false}>
|
|
59
|
+
Link Text
|
|
60
|
+
</ConditionalLink>
|
|
61
|
+
</MemoryRouter>
|
|
62
|
+
</Provider>,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const span = screen.getByText('Link Text');
|
|
66
|
+
expect(span.tagName).toBe('DIV');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('passes additional props when rendering a link', () => {
|
|
70
|
+
render(
|
|
71
|
+
<Provider store={store}>
|
|
72
|
+
<MemoryRouter>
|
|
73
|
+
<ConditionalLink
|
|
74
|
+
to="/test"
|
|
75
|
+
condition={true}
|
|
76
|
+
className="custom-class"
|
|
77
|
+
data-test="test-id"
|
|
78
|
+
>
|
|
79
|
+
Link Text
|
|
80
|
+
</ConditionalLink>
|
|
81
|
+
</MemoryRouter>
|
|
82
|
+
</Provider>,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const link = screen.getByText('Link Text');
|
|
86
|
+
expect(link).toHaveClass('custom-class');
|
|
87
|
+
expect(link).toHaveAttribute('data-test', 'test-id');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('renders a component if no external (href) link is passed', () => {
|
|
91
|
+
render(
|
|
92
|
+
<Provider store={store}>
|
|
93
|
+
<MemoryRouter>
|
|
94
|
+
<ConditionalLink
|
|
95
|
+
condition={true}
|
|
96
|
+
item={{
|
|
97
|
+
'@id': 'http://localhost:3000/en/welcome-to-volto',
|
|
98
|
+
}}
|
|
99
|
+
>
|
|
100
|
+
<h1>Title</h1>
|
|
101
|
+
</ConditionalLink>
|
|
102
|
+
</MemoryRouter>
|
|
103
|
+
</Provider>,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const title = screen.getByText('Title');
|
|
107
|
+
expect(title.tagName).toBe('H1');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
|
|
3
|
+
import type { UniversalLinkProps } from '@plone/volto/components/manage/UniversalLink/UniversalLink';
|
|
4
|
+
|
|
5
|
+
type ConditionalLinkProps = {
|
|
6
|
+
condition?: boolean;
|
|
7
|
+
to?: string; // Alias for href
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
} & Omit<UniversalLinkProps, 'href' | 'item'> & {
|
|
10
|
+
href?: string;
|
|
11
|
+
item?: UniversalLinkProps['item'];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const ConditionalLink = React.forwardRef<
|
|
15
|
+
HTMLAnchorElement | HTMLDivElement,
|
|
16
|
+
ConditionalLinkProps
|
|
17
|
+
>(function ConditionalLink(
|
|
18
|
+
{ condition = true, to, href, item, children, ...rest },
|
|
19
|
+
ref,
|
|
20
|
+
) {
|
|
21
|
+
if (!condition) {
|
|
22
|
+
return <>{children}</>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Normalize: prefer explicit href over "to"
|
|
26
|
+
const finalHref = href ?? to;
|
|
27
|
+
|
|
28
|
+
// Rebuild props safely to satisfy UniversalLinkProps union
|
|
29
|
+
const universalLinkProps: UniversalLinkProps = finalHref
|
|
30
|
+
? { ...rest, href: finalHref, children }
|
|
31
|
+
: { ...rest, item: item!, children }; // assume item is defined if href isn't
|
|
32
|
+
|
|
33
|
+
return <UniversalLink ref={ref} {...universalLinkProps} />;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export default React.memo(ConditionalLink);
|
|
@@ -8,20 +8,29 @@ import { __test__ as Contents } from './Contents';
|
|
|
8
8
|
|
|
9
9
|
const mockStore = configureStore();
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
);
|
|
11
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
|
|
12
|
+
return await import(
|
|
13
|
+
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
beforeAll(async () => {
|
|
18
|
+
const { __setLoadables } = await import(
|
|
19
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
20
|
+
);
|
|
21
|
+
await __setLoadables();
|
|
22
|
+
});
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
vi.mock('../Toolbar/Toolbar', () => ({
|
|
25
|
+
default: vi.fn(() => <div id="Portal" />),
|
|
26
|
+
}));
|
|
18
27
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
);
|
|
28
|
+
vi.mock('../../theme/Pagination/Pagination', () => ({
|
|
29
|
+
default: vi.fn(() => <div className="Pagination" />),
|
|
30
|
+
}));
|
|
31
|
+
vi.mock('./ContentsUploadModal', () => ({
|
|
32
|
+
default: vi.fn(() => <div className="UploadModal" />),
|
|
33
|
+
}));
|
|
25
34
|
|
|
26
35
|
describe('Contents', () => {
|
|
27
36
|
it('renders a folder contents view component', () => {
|
|
@@ -87,7 +96,14 @@ describe('Contents', () => {
|
|
|
87
96
|
},
|
|
88
97
|
intl: {
|
|
89
98
|
locale: 'en',
|
|
90
|
-
messages: {
|
|
99
|
+
messages: {
|
|
100
|
+
ID: 'ID',
|
|
101
|
+
Title: 'Title',
|
|
102
|
+
'Publication date': 'Publication date',
|
|
103
|
+
'Created on': 'Created on',
|
|
104
|
+
'Last modified': 'Last modified',
|
|
105
|
+
Type: 'Type',
|
|
106
|
+
},
|
|
91
107
|
},
|
|
92
108
|
});
|
|
93
109
|
const { container } = render(
|
|
@@ -7,7 +7,11 @@ import ContentsPropertiesModal from './ContentsPropertiesModal';
|
|
|
7
7
|
|
|
8
8
|
const mockStore = configureStore();
|
|
9
9
|
|
|
10
|
-
|
|
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
|
+
});
|
|
11
15
|
|
|
12
16
|
describe('ContentsPropertiesModal', () => {
|
|
13
17
|
it('renders a contents properties modal component', () => {
|
|
@@ -7,7 +7,11 @@ import ContentsRenameModal from './ContentsRenameModal';
|
|
|
7
7
|
|
|
8
8
|
const mockStore = configureStore();
|
|
9
9
|
|
|
10
|
-
|
|
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
|
+
});
|
|
11
15
|
|
|
12
16
|
describe('ContentsRenameModal', () => {
|
|
13
17
|
it('renders a contents rename modal component', () => {
|
|
@@ -7,7 +7,11 @@ import ContentsTagsModal from './ContentsTagsModal';
|
|
|
7
7
|
|
|
8
8
|
const mockStore = configureStore();
|
|
9
9
|
|
|
10
|
-
|
|
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
|
+
});
|
|
11
15
|
|
|
12
16
|
describe('ContentsTagsModal', () => {
|
|
13
17
|
it('renders a contents tags modal component', () => {
|