@plone/volto 19.0.0-alpha.0 → 19.0.0-alpha.1
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 +46 -2
- package/package.json +14 -7
- 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/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.test.jsx +5 -1
- 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.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/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/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/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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { HashLink as Link } from 'react-router-hash-link';
|
|
3
|
+
import { useSelector } from 'react-redux';
|
|
4
|
+
import {
|
|
5
|
+
flattenToAppURL,
|
|
6
|
+
isInternalURL,
|
|
7
|
+
URLUtils,
|
|
8
|
+
} from '@plone/volto/helpers/Url/Url';
|
|
9
|
+
import config from '@plone/volto/registry';
|
|
10
|
+
import cx from 'classnames';
|
|
11
|
+
import type { ObjectBrowserItem } from '@plone/types';
|
|
12
|
+
|
|
13
|
+
type BaseProps = {
|
|
14
|
+
openLinkInNewTab?: boolean;
|
|
15
|
+
download?: boolean;
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
className?: string;
|
|
18
|
+
title?: string;
|
|
19
|
+
smooth?: boolean;
|
|
20
|
+
onClick?: (e: React.MouseEvent) => void;
|
|
21
|
+
onKeyDown?: (e: React.KeyboardEvent) => void;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type HrefOnly = {
|
|
25
|
+
href: string;
|
|
26
|
+
item?: never;
|
|
27
|
+
} & BaseProps;
|
|
28
|
+
|
|
29
|
+
type ItemOnly = {
|
|
30
|
+
href?: never;
|
|
31
|
+
item: Partial<ObjectBrowserItem> & { remoteUrl?: string };
|
|
32
|
+
} & BaseProps;
|
|
33
|
+
|
|
34
|
+
export type UniversalLinkProps = HrefOnly | ItemOnly;
|
|
35
|
+
export interface AppState {
|
|
36
|
+
content: {
|
|
37
|
+
data?: {
|
|
38
|
+
'@components'?: {
|
|
39
|
+
translations?: {
|
|
40
|
+
items?: { language: string; '@id': string }[];
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
navroot: {
|
|
46
|
+
data: {
|
|
47
|
+
navroot: {
|
|
48
|
+
id: string;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
intl: {
|
|
53
|
+
locale: string;
|
|
54
|
+
};
|
|
55
|
+
userSession: {
|
|
56
|
+
token: string | null;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const __test = {
|
|
61
|
+
renderCounter: () => {},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export function getUrl(
|
|
65
|
+
props: UniversalLinkProps,
|
|
66
|
+
token: string | null,
|
|
67
|
+
item: UniversalLinkProps['item'],
|
|
68
|
+
children: React.ReactNode,
|
|
69
|
+
): string {
|
|
70
|
+
if ('href' in props && typeof props.href === 'string') {
|
|
71
|
+
return props.href;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!item || item['@id'] === '') return config.settings.publicURL;
|
|
75
|
+
if (!item['@id']) {
|
|
76
|
+
// eslint-disable-next-line no-console
|
|
77
|
+
console.error(
|
|
78
|
+
'Invalid item passed to UniversalLink',
|
|
79
|
+
item,
|
|
80
|
+
props,
|
|
81
|
+
children,
|
|
82
|
+
);
|
|
83
|
+
return '#';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let url = flattenToAppURL(item['@id']);
|
|
87
|
+
const remoteUrl = item.remoteUrl || item.getRemoteUrl;
|
|
88
|
+
|
|
89
|
+
if (!token && remoteUrl) {
|
|
90
|
+
url = remoteUrl;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (
|
|
94
|
+
!token &&
|
|
95
|
+
item['@type'] &&
|
|
96
|
+
config.settings.downloadableObjects.includes(item['@type'])
|
|
97
|
+
) {
|
|
98
|
+
url = `${url}/@@download/file`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (
|
|
102
|
+
!token &&
|
|
103
|
+
item['@type'] &&
|
|
104
|
+
config.settings.viewableInBrowserObjects.includes(item['@type'])
|
|
105
|
+
) {
|
|
106
|
+
url = `${url}/@@display-file/file`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return url;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const UniversalLink = React.memo(
|
|
113
|
+
React.forwardRef<HTMLAnchorElement | HTMLDivElement, UniversalLinkProps>(
|
|
114
|
+
function UniversalLink(props, ref) {
|
|
115
|
+
const {
|
|
116
|
+
openLinkInNewTab,
|
|
117
|
+
download,
|
|
118
|
+
children,
|
|
119
|
+
className,
|
|
120
|
+
title,
|
|
121
|
+
smooth,
|
|
122
|
+
onClick,
|
|
123
|
+
onKeyDown,
|
|
124
|
+
item,
|
|
125
|
+
...rest
|
|
126
|
+
} = props;
|
|
127
|
+
__test.renderCounter();
|
|
128
|
+
|
|
129
|
+
const token = useSelector<AppState, string | null>(
|
|
130
|
+
(state) => state.userSession?.token,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
let url = getUrl(props, token, item, children);
|
|
134
|
+
|
|
135
|
+
const isExternal = !isInternalURL(url);
|
|
136
|
+
|
|
137
|
+
const isDownload =
|
|
138
|
+
(!isExternal && url.includes('@@download')) || download;
|
|
139
|
+
const isDisplayFile =
|
|
140
|
+
(!isExternal && url.includes('@@display-file')) || false;
|
|
141
|
+
|
|
142
|
+
const checkedURL = URLUtils.checkAndNormalizeUrl(url);
|
|
143
|
+
|
|
144
|
+
url = checkedURL.url;
|
|
145
|
+
let tag = (
|
|
146
|
+
<Link
|
|
147
|
+
to={flattenToAppURL(url)}
|
|
148
|
+
target={openLinkInNewTab ?? false ? '_blank' : undefined}
|
|
149
|
+
title={title}
|
|
150
|
+
className={className}
|
|
151
|
+
smooth={smooth ?? config.settings.hashLinkSmoothScroll}
|
|
152
|
+
// @ts-ignore
|
|
153
|
+
ref={ref}
|
|
154
|
+
{...rest}
|
|
155
|
+
>
|
|
156
|
+
{children}
|
|
157
|
+
</Link>
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
if (isExternal) {
|
|
161
|
+
const isTelephoneOrMail = checkedURL.isMail || checkedURL.isTelephone;
|
|
162
|
+
const getClassName = cx({ external: !isTelephoneOrMail }, className);
|
|
163
|
+
|
|
164
|
+
tag = (
|
|
165
|
+
<a
|
|
166
|
+
href={url}
|
|
167
|
+
title={title}
|
|
168
|
+
target={
|
|
169
|
+
!isTelephoneOrMail && !(openLinkInNewTab === false)
|
|
170
|
+
? '_blank'
|
|
171
|
+
: undefined
|
|
172
|
+
}
|
|
173
|
+
rel="noopener noreferrer"
|
|
174
|
+
{...rest}
|
|
175
|
+
className={getClassName}
|
|
176
|
+
ref={ref as React.Ref<HTMLAnchorElement>}
|
|
177
|
+
>
|
|
178
|
+
{children}
|
|
179
|
+
</a>
|
|
180
|
+
);
|
|
181
|
+
} else if (isDownload) {
|
|
182
|
+
tag = (
|
|
183
|
+
<a
|
|
184
|
+
href={flattenToAppURL(url)}
|
|
185
|
+
download
|
|
186
|
+
title={title}
|
|
187
|
+
{...rest}
|
|
188
|
+
className={className}
|
|
189
|
+
ref={ref as React.Ref<HTMLAnchorElement>}
|
|
190
|
+
>
|
|
191
|
+
{children}
|
|
192
|
+
</a>
|
|
193
|
+
);
|
|
194
|
+
} else if (isDisplayFile) {
|
|
195
|
+
tag = (
|
|
196
|
+
<a
|
|
197
|
+
title={title}
|
|
198
|
+
target="_blank"
|
|
199
|
+
rel="noopener noreferrer"
|
|
200
|
+
{...rest}
|
|
201
|
+
href={flattenToAppURL(url)}
|
|
202
|
+
className={className}
|
|
203
|
+
ref={ref as React.Ref<HTMLAnchorElement>}
|
|
204
|
+
>
|
|
205
|
+
{children}
|
|
206
|
+
</a>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return tag;
|
|
210
|
+
},
|
|
211
|
+
),
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
export default UniversalLink;
|
|
@@ -8,11 +8,25 @@ import ArrayWidget from './ArrayWidget';
|
|
|
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
|
+
// Mock react-sortable-hoc to prevent the container error
|
|
18
|
+
vi.mock('react-sortable-hoc', () => ({
|
|
19
|
+
...vi.importActual('react-sortable-hoc'),
|
|
20
|
+
SortableContainer: (component) => component,
|
|
21
|
+
SortableElement: (component) => component,
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
beforeAll(async () => {
|
|
25
|
+
const { __setLoadables } = await import(
|
|
26
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
27
|
+
);
|
|
28
|
+
await __setLoadables();
|
|
29
|
+
});
|
|
16
30
|
|
|
17
31
|
test('renders an array widget component', async () => {
|
|
18
32
|
const store = mockStore({
|
|
@@ -27,6 +41,7 @@ test('renders an array widget component', async () => {
|
|
|
27
41
|
},
|
|
28
42
|
},
|
|
29
43
|
});
|
|
44
|
+
|
|
30
45
|
const component = renderer.create(
|
|
31
46
|
<Provider store={store}>
|
|
32
47
|
<ArrayWidget
|
|
@@ -38,6 +53,7 @@ test('renders an array widget component', async () => {
|
|
|
38
53
|
/>
|
|
39
54
|
</Provider>,
|
|
40
55
|
);
|
|
56
|
+
|
|
41
57
|
await waitFor(() => {});
|
|
42
58
|
expect(component.toJSON()).toMatchSnapshot();
|
|
43
59
|
});
|
|
@@ -83,5 +99,6 @@ test("No 'No value' option when default value is 0", async () => {
|
|
|
83
99
|
container.querySelector('.react-select__dropdown-indicator'),
|
|
84
100
|
{ button: 0 },
|
|
85
101
|
);
|
|
102
|
+
|
|
86
103
|
expect(container).toMatchSnapshot();
|
|
87
104
|
});
|
|
@@ -7,11 +7,18 @@ import CheckboxGroupWidget from './CheckboxGroupWidget';
|
|
|
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 a checkbox group widget component', async () => {
|
|
17
24
|
const store = mockStore({
|
|
@@ -6,11 +6,18 @@ import { waitFor, render, screen } from '@testing-library/react';
|
|
|
6
6
|
|
|
7
7
|
const mockStore = configureStore();
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
);
|
|
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
|
+
});
|
|
14
21
|
|
|
15
22
|
test('renders a datetime widget component', async () => {
|
|
16
23
|
const store = mockStore({
|
|
@@ -19,6 +26,7 @@ test('renders a datetime widget component', async () => {
|
|
|
19
26
|
messages: {},
|
|
20
27
|
},
|
|
21
28
|
});
|
|
29
|
+
|
|
22
30
|
const isoDate = new Date('2019-10-21').toISOString();
|
|
23
31
|
const { container } = render(
|
|
24
32
|
<Provider store={store}>
|
|
@@ -28,20 +36,24 @@ test('renders a datetime widget component', async () => {
|
|
|
28
36
|
fieldSet="default"
|
|
29
37
|
onChange={() => {}}
|
|
30
38
|
value={isoDate}
|
|
39
|
+
showTime={true}
|
|
31
40
|
/>
|
|
32
41
|
</Provider>,
|
|
33
42
|
);
|
|
43
|
+
|
|
34
44
|
await waitFor(() => screen.getByText(/My field/));
|
|
45
|
+
await waitFor(() => screen.getByPlaceholderText('Time'));
|
|
35
46
|
expect(container).toMatchSnapshot();
|
|
36
47
|
});
|
|
37
48
|
|
|
38
|
-
test('datetime widget converts UTC date and
|
|
49
|
+
test('datetime widget converts UTC date and adapts to local datetime', async () => {
|
|
39
50
|
const store = mockStore({
|
|
40
51
|
intl: {
|
|
41
52
|
locale: 'en',
|
|
42
53
|
messages: {},
|
|
43
54
|
},
|
|
44
55
|
});
|
|
56
|
+
|
|
45
57
|
const date = '2020-02-10T15:01:00.000Z';
|
|
46
58
|
const { container } = render(
|
|
47
59
|
<Provider store={store}>
|
|
@@ -50,9 +62,12 @@ test('datetime widget converts UTC date and adapt to local datetime', async () =
|
|
|
50
62
|
title="My field"
|
|
51
63
|
onChange={() => {}}
|
|
52
64
|
value={date}
|
|
65
|
+
showTime={true}
|
|
53
66
|
/>
|
|
54
67
|
</Provider>,
|
|
55
68
|
);
|
|
69
|
+
|
|
56
70
|
await waitFor(() => screen.getByText(/My field/));
|
|
71
|
+
await waitFor(() => screen.getByPlaceholderText('Time'));
|
|
57
72
|
expect(container).toMatchSnapshot();
|
|
58
73
|
});
|
|
@@ -131,7 +131,10 @@ const UnconnectedImageInput = (props) => {
|
|
|
131
131
|
const file = eventOrFile.target
|
|
132
132
|
? eventOrFile.target.files[0]
|
|
133
133
|
: eventOrFile[0];
|
|
134
|
-
if (!validateFileUploadSize(file, intl.formatMessage))
|
|
134
|
+
if (!validateFileUploadSize(file, intl.formatMessage)) {
|
|
135
|
+
setUploading(false);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
135
138
|
readAsDataURL(file).then((fileData) => {
|
|
136
139
|
const fields = fileData.match(/^data:(.*);(.*),(.*)$/);
|
|
137
140
|
dispatch(
|
|
@@ -196,10 +199,10 @@ const UnconnectedImageInput = (props) => {
|
|
|
196
199
|
noClick
|
|
197
200
|
accept="image/*"
|
|
198
201
|
onDrop={(acceptedFiles) => {
|
|
202
|
+
setDragging(false);
|
|
199
203
|
if (acceptedFiles.length > 0) {
|
|
200
204
|
handleUpload(acceptedFiles);
|
|
201
205
|
} else {
|
|
202
|
-
setDragging(false);
|
|
203
206
|
toast.error(
|
|
204
207
|
<Toast
|
|
205
208
|
error
|
|
@@ -16,13 +16,14 @@ test('renders a number widget component', () => {
|
|
|
16
16
|
});
|
|
17
17
|
const component = renderer.create(
|
|
18
18
|
<Provider store={store}>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
<>
|
|
20
|
+
<NumberWidget
|
|
21
|
+
id="my-field"
|
|
22
|
+
title="My field"
|
|
23
|
+
fieldSet="default"
|
|
24
|
+
onChange={() => {}}
|
|
25
|
+
/>
|
|
26
|
+
</>
|
|
26
27
|
</Provider>,
|
|
27
28
|
);
|
|
28
29
|
const json = component.toJSON();
|
|
@@ -14,6 +14,7 @@ import deleteSVG from '@plone/volto/icons/delete.svg';
|
|
|
14
14
|
import addSVG from '@plone/volto/icons/add.svg';
|
|
15
15
|
import dragSVG from '@plone/volto/icons/drag.svg';
|
|
16
16
|
import { v4 as uuid } from 'uuid';
|
|
17
|
+
import config from '@plone/volto/registry';
|
|
17
18
|
|
|
18
19
|
const messages = defineMessages({
|
|
19
20
|
labelRemoveItem: {
|
|
@@ -71,11 +72,20 @@ const ObjectListWidget = (props) => {
|
|
|
71
72
|
block,
|
|
72
73
|
fieldSet,
|
|
73
74
|
id,
|
|
74
|
-
schema,
|
|
75
75
|
value = [],
|
|
76
76
|
onChange,
|
|
77
77
|
schemaExtender,
|
|
78
|
+
schemaName,
|
|
78
79
|
} = props;
|
|
80
|
+
|
|
81
|
+
// This allows to use a `schemaName` prop defined as source of the schema
|
|
82
|
+
// if not present, it will use the schema defined in the schema prop
|
|
83
|
+
const schema =
|
|
84
|
+
config.getUtility({
|
|
85
|
+
type: 'schema',
|
|
86
|
+
name: schemaName,
|
|
87
|
+
}).method || props.schema;
|
|
88
|
+
|
|
79
89
|
const [localActiveObject, setLocalActiveObject] = React.useState(
|
|
80
90
|
props.activeObject ?? value.length - 1,
|
|
81
91
|
);
|
|
@@ -4,20 +4,30 @@ import { render } from '@testing-library/react';
|
|
|
4
4
|
import configureStore from 'redux-mock-store';
|
|
5
5
|
import ObjectListWidget from './ObjectListWidget';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
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
|
+
vi.mock('@plone/volto/components/manage/Form', async () => {
|
|
13
|
+
return await import(
|
|
14
|
+
'@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
|
|
15
|
+
);
|
|
16
|
+
});
|
|
9
17
|
|
|
10
|
-
beforeAll(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
);
|
|
18
|
+
beforeAll(async () => {
|
|
19
|
+
const { __setLoadables } = await import(
|
|
20
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
21
|
+
);
|
|
22
|
+
await __setLoadables();
|
|
23
|
+
});
|
|
14
24
|
|
|
15
25
|
let mockSerial = 0;
|
|
16
26
|
const mockStore = configureStore();
|
|
17
27
|
|
|
18
|
-
|
|
28
|
+
vi.mock('uuid', () => {
|
|
19
29
|
return {
|
|
20
|
-
v4:
|
|
30
|
+
v4: vi.fn().mockImplementation(() => `id-${mockSerial++}`),
|
|
21
31
|
};
|
|
22
32
|
});
|
|
23
33
|
|
|
@@ -5,7 +5,11 @@ import { Provider } from 'react-intl-redux';
|
|
|
5
5
|
import { render, fireEvent } from '@testing-library/react';
|
|
6
6
|
import ObjectWidget from './ObjectWidget';
|
|
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
|
|
|
@@ -7,11 +7,18 @@ import RadioGroupWidget from './RadioGroupWidget';
|
|
|
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 a radio group widget component', async () => {
|
|
17
24
|
const store = mockStore({
|
|
@@ -3,14 +3,20 @@ 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 { waitFor } from '@testing-library/react';
|
|
6
|
-
|
|
7
6
|
import RecurrenceWidget from './RecurrenceWidget';
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
);
|
|
8
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
|
|
9
|
+
return await import(
|
|
10
|
+
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
11
|
+
);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
beforeAll(async () => {
|
|
15
|
+
const { __setLoadables } = await import(
|
|
16
|
+
'@plone/volto/helpers/Loadable/Loadable'
|
|
17
|
+
);
|
|
18
|
+
await __setLoadables();
|
|
19
|
+
});
|
|
14
20
|
|
|
15
21
|
const mockStore = configureStore();
|
|
16
22
|
|