@plone/volto 18.11.0 → 18.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/.eslintignore +1 -0
  2. package/.eslintrc +2 -0
  3. package/CHANGELOG.md +27 -0
  4. package/cypress/support/commands.js +19 -2
  5. package/locales/eu.json +1 -1
  6. package/package.json +10 -4
  7. package/src/actions/actions/actions.test.js +3 -3
  8. package/src/actions/addons/addons.test.js +15 -12
  9. package/src/actions/aliases/aliases.test.js +1 -1
  10. package/src/actions/types/types.test.js +1 -1
  11. package/src/components/manage/Actions/Actions.test.jsx +1 -1
  12. package/src/components/manage/Add/Add.test.jsx +6 -3
  13. package/src/components/manage/Aliases/Aliases.test.jsx +7 -7
  14. package/src/components/manage/Blocks/Block/BlocksForm.jsx +3 -3
  15. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +44 -16
  16. package/src/components/manage/Blocks/Block/Settings.test.jsx +1 -1
  17. package/src/components/manage/Blocks/Description/View.test.jsx +1 -1
  18. package/src/components/manage/Blocks/HTML/Edit.test.jsx +7 -5
  19. package/src/components/manage/Blocks/HTML/View.test.jsx +1 -1
  20. package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +2 -2
  21. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +3 -1
  22. package/src/components/manage/Blocks/Listing/View.test.jsx +3 -1
  23. package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +1 -1
  24. package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +8 -7
  25. package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +7 -6
  26. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.test.jsx +11 -1
  27. package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +1 -1
  28. package/src/components/manage/Contents/Contents.test.jsx +24 -13
  29. package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +1 -1
  30. package/src/components/manage/Contents/ContentsRenameModal.test.jsx +1 -1
  31. package/src/components/manage/Contents/ContentsTagsModal.test.jsx +1 -1
  32. package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +1 -1
  33. package/src/components/manage/Contents/__mocks__/index.tsx +3 -2
  34. package/src/components/manage/Controlpanels/AddonsControlpanel.test.jsx +28 -3
  35. package/src/components/manage/Controlpanels/Aliases.test.jsx +30 -3
  36. package/src/components/manage/Controlpanels/ContentType.test.jsx +25 -3
  37. package/src/components/manage/Controlpanels/ContentTypeLayout.test.jsx +4 -2
  38. package/src/components/manage/Controlpanels/ContentTypes.test.jsx +25 -2
  39. package/src/components/manage/Controlpanels/Controlpanel.test.jsx +37 -6
  40. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +47 -3
  41. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.test.jsx +15 -9
  42. package/src/components/manage/Controlpanels/ModerateComments.test.jsx +31 -5
  43. package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +8 -4
  44. package/src/components/manage/Controlpanels/Rules/ConfigureRule.test.jsx +9 -5
  45. package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +8 -4
  46. package/src/components/manage/Controlpanels/Rules/Rules.test.jsx +7 -3
  47. package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +29 -4
  48. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +3 -1
  49. package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +15 -9
  50. package/src/components/manage/Delete/Delete.test.jsx +45 -4
  51. package/src/components/manage/Diff/Diff.test.jsx +12 -6
  52. package/src/components/manage/Diff/DiffField.test.jsx +7 -6
  53. package/src/components/manage/Display/Display.test.jsx +8 -6
  54. package/src/components/manage/Edit/Edit.test.jsx +7 -3
  55. package/src/components/manage/Form/BlockDataForm.test.jsx +1 -1
  56. package/src/components/manage/Form/Form.test.jsx +1 -1
  57. package/src/components/manage/Form/InlineForm.test.jsx +1 -1
  58. package/src/components/manage/Form/ModalForm.test.jsx +1 -1
  59. package/src/components/manage/Form/__mocks__/index.tsx +10 -10
  60. package/src/components/manage/History/History.test.jsx +3 -1
  61. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +6 -4
  62. package/src/components/manage/Multilingual/ManageTranslations.test.jsx +3 -2
  63. package/src/components/manage/Preferences/ChangePassword.test.jsx +4 -2
  64. package/src/components/manage/Preferences/PersonalInformation.test.jsx +3 -1
  65. package/src/components/manage/Preferences/PersonalPreferences.test.jsx +11 -7
  66. package/src/components/manage/Rules/Rules.test.jsx +6 -3
  67. package/src/components/manage/Sharing/Sharing.test.jsx +3 -1
  68. package/src/components/manage/Sidebar/ObjectBrowserNav.test.jsx +3 -3
  69. package/src/components/manage/Toolbar/More.test.jsx +6 -7
  70. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +1 -1
  71. package/src/components/manage/Widgets/ArrayWidget.test.jsx +18 -5
  72. package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +7 -5
  73. package/src/components/manage/Widgets/DatetimeWidget.test.jsx +17 -6
  74. package/src/components/manage/Widgets/FileWidget.jsx +3 -3
  75. package/src/components/manage/Widgets/FileWidget.test.jsx +54 -22
  76. package/src/components/manage/Widgets/NumberWidget.test.jsx +8 -7
  77. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +3 -2
  78. package/src/components/manage/Widgets/ObjectListWidget.test.jsx +10 -8
  79. package/src/components/manage/Widgets/ObjectWidget.test.jsx +1 -1
  80. package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +7 -5
  81. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +7 -6
  82. package/src/components/manage/Widgets/RegistryImageWidget.jsx +3 -3
  83. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +43 -41
  84. package/src/components/manage/Widgets/SchemaWidget.test.jsx +7 -5
  85. package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +7 -5
  86. package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +7 -6
  87. package/src/components/manage/Widgets/SelectWidget.test.jsx +7 -6
  88. package/src/components/manage/Widgets/TimeWidget.test.jsx +8 -5
  89. package/src/components/manage/Widgets/TokenWidget.test.jsx +7 -6
  90. package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +10 -9
  91. package/src/components/manage/Widgets/__mocks__/index.tsx +35 -35
  92. package/src/components/manage/Workflow/Workflow.test.jsx +8 -7
  93. package/src/components/theme/App/App.test.jsx +21 -17
  94. package/src/components/theme/AppExtras/AppExtras.test.jsx +8 -6
  95. package/src/components/theme/Comments/CommentEditModal.test.jsx +1 -1
  96. package/src/components/theme/Comments/Comments.test.jsx +21 -12
  97. package/src/components/theme/ContactForm/ContactForm.test.jsx +4 -4
  98. package/src/components/theme/Header/Header.test.jsx +19 -13
  99. package/src/components/theme/Logo/Logo.jsx +2 -1
  100. package/src/components/theme/Logout/Logout.test.jsx +1 -1
  101. package/src/components/theme/Navigation/ContextNavigation.jsx +7 -2
  102. package/src/components/theme/PasswordReset/PasswordReset.test.jsx +10 -1
  103. package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +1 -1
  104. package/src/components/theme/Register/Register.test.jsx +1 -1
  105. package/src/components/theme/Search/Search.test.jsx +6 -4
  106. package/src/components/theme/TsTest/TsTest.test.tsx +0 -1
  107. package/src/components/theme/View/EventDatesInfo.test.jsx +7 -5
  108. package/src/components/theme/View/EventView.test.jsx +7 -5
  109. package/src/components/theme/View/ListingView.test.jsx +2 -0
  110. package/src/components/theme/View/SummaryView.test.jsx +10 -0
  111. package/src/components/theme/View/TabularView.test.jsx +1 -0
  112. package/src/components/theme/View/View.test.jsx +42 -23
  113. package/src/helpers/Api/Api.plone.rest.test.js +12 -9
  114. package/src/helpers/Api/Api.test.js +12 -9
  115. package/src/helpers/AsyncConnect/AsyncConnect.test.jsx +145 -189
  116. package/src/helpers/AuthToken/AuthToken.test.js +61 -22
  117. package/src/helpers/Blocks/Blocks.js +1 -1
  118. package/src/helpers/Blocks/Blocks.test.js +1 -1
  119. package/src/helpers/Html/Html.test.jsx +32 -28
  120. package/src/helpers/Loadable/__mocks__/Loadable.jsx +7 -6
  121. package/src/middleware/storeProtectLoadUtils.test.js +90 -78
  122. package/test-setup-globals.js +36 -2
  123. package/tsconfig.json +23 -6
  124. package/types/components/manage/Contents/__mocks__/index.d.ts +2 -2
  125. package/types/components/manage/Form/__mocks__/index.d.ts +8 -8
  126. package/types/components/manage/Widgets/__mocks__/index.d.ts +33 -33
  127. package/types/helpers/Loadable/__mocks__/Loadable.d.ts +2 -2
  128. package/types/server.d.ts +1 -1
  129. package/vite-plugins/svg.js +81 -0
  130. package/vitest.config.ts +61 -0
@@ -8,12 +8,14 @@ import Display from './Display';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('@plone/volto/components/manage/Widgets');
12
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
13
- beforeAll(
14
- async () =>
15
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
16
- );
11
+ vi.mock('@plone/volto/components/manage/Widgets');
12
+ vi.mock('@plone/volto/helpers/Loadable/Loadable');
13
+ beforeAll(async () => {
14
+ const { __setLoadables } = await import(
15
+ '@plone/volto/helpers/Loadable/Loadable'
16
+ );
17
+ await __setLoadables();
18
+ });
17
19
 
18
20
  beforeEach(() => {
19
21
  config.views.layoutViewsNamesMapping = {
@@ -8,9 +8,13 @@ import { __test__ as Edit } from './Edit';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('@plone/volto/components/manage/Form');
12
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
13
- jest.mock('../Sidebar/Sidebar', () => jest.fn(() => <div id="Sidebar" />));
11
+ vi.mock('@plone/volto/components/manage/Form');
12
+ vi.mock('../Toolbar/Toolbar', () => ({
13
+ default: vi.fn(() => <div id="Portal" />),
14
+ }));
15
+ vi.mock('../Sidebar/Sidebar', () => ({
16
+ default: vi.fn(() => <div id="Sidebar" />),
17
+ }));
14
18
 
15
19
  describe('Edit', () => {
16
20
  it('renders an empty edit component', () => {
@@ -5,7 +5,7 @@ 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
- jest.mock('@plone/volto/components/manage/Form');
8
+ vi.mock('@plone/volto/components/manage/Form');
9
9
 
10
10
  const mockStore = configureStore();
11
11
 
@@ -9,7 +9,7 @@ const mockStore = configureStore();
9
9
  const errorMessage =
10
10
  "[{'message': 'The specified email is not valid.', 'field': 'contact_email', 'error': 'ValidationError'}";
11
11
 
12
- jest.mock('@plone/volto/components/manage/Form');
12
+ vi.mock('@plone/volto/components/manage/Form');
13
13
 
14
14
  describe('Form', () => {
15
15
  it('renders a form component', () => {
@@ -6,7 +6,7 @@ import config from '@plone/volto/registry';
6
6
 
7
7
  import InlineForm from './InlineForm';
8
8
 
9
- jest.mock('@plone/volto/components/manage/Form');
9
+ vi.mock('@plone/volto/components/manage/Form');
10
10
 
11
11
  const mockStore = configureStore();
12
12
 
@@ -8,7 +8,7 @@ import ModalForm from './ModalForm';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('@plone/volto/components/manage/Form');
11
+ vi.mock('@plone/volto/components/manage/Form');
12
12
 
13
13
  describe('ModalForm', () => {
14
14
  it('renders a modal form component', () => {
@@ -1,8 +1,8 @@
1
1
  import type { JSONSchema } from '@plone/types';
2
2
  import type { Ref } from 'react';
3
- const { forwardRef } = jest.requireActual('react');
3
+ import { vi } from 'vitest';
4
+ import { forwardRef } from 'react';
4
5
 
5
- // Field descriptions can contain react elements and those are not JSON stringifiable
6
6
  const cleanupSchema = (schema: JSONSchema | null): JSONSchema | null => {
7
7
  if (!schema || !schema.properties) return schema;
8
8
  return {
@@ -23,38 +23,38 @@ const cleanupSchema = (schema: JSONSchema | null): JSONSchema | null => {
23
23
  };
24
24
  };
25
25
 
26
- export const Field = jest.fn((props) => (
26
+ export const Field = vi.fn((props) => (
27
27
  <div className="Field" id={props.id}>
28
28
  {props.title}
29
29
  </div>
30
30
  ));
31
31
 
32
- export const InlineForm = jest.fn((props) => (
32
+ export const InlineForm = vi.fn((props) => (
33
33
  <div
34
34
  id="InlineForm"
35
35
  data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
36
36
  />
37
37
  ));
38
38
 
39
- export const ModalForm = jest.fn((props) => (
39
+ export const ModalForm = vi.fn((props) => (
40
40
  <div
41
41
  id="ModalForm"
42
42
  data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
43
43
  />
44
44
  ));
45
45
 
46
- export const UndoToolbar = jest.fn(() => <div id="UndoToolbar" />);
46
+ export const UndoToolbar = vi.fn(() => <div id="UndoToolbar" />);
47
47
 
48
- export const BlocksToolbar = jest.fn(() => <div id="BlocksToolbar" />);
48
+ export const BlocksToolbar = vi.fn(() => <div id="BlocksToolbar" />);
49
49
 
50
- export const BlockDataForm = jest.fn((props) => (
50
+ export const BlockDataForm = vi.fn((props) => (
51
51
  <div
52
52
  id="BlockDataForm"
53
53
  data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
54
54
  />
55
55
  ));
56
56
 
57
- export const BlocksForm = jest.fn((props) => (
57
+ export const BlocksForm = vi.fn((props) => (
58
58
  <div
59
59
  id="BlocksForm"
60
60
  data-schema={JSON.stringify(cleanupSchema(props.schema), null, 2)}
@@ -71,4 +71,4 @@ const MockForm = forwardRef(
71
71
  ),
72
72
  );
73
73
 
74
- export const Form = jest.fn((props) => <MockForm {...props} />);
74
+ 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
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
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
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
14
-
15
- jest.mock('../Toolbar/More', () => jest.fn(() => <div className="More" />));
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({
@@ -11,8 +11,9 @@ beforeAll(() => {
11
11
  config.settings.isMultilingual = true;
12
12
  config.settings.supportedLanguages = ['de', 'es'];
13
13
  });
14
-
15
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
14
+ vi.mock('../Toolbar/Toolbar', () => ({
15
+ default: vi.fn(() => <div id="Portal" />),
16
+ }));
16
17
 
17
18
  const mockStore = configureStore();
18
19
 
@@ -9,8 +9,10 @@ import ChangePassword from './ChangePassword';
9
9
 
10
10
  const mockStore = configureStore();
11
11
 
12
- jest.mock('@plone/volto/components/manage/Form');
13
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
12
+ vi.mock('@plone/volto/components/manage/Form');
13
+ vi.mock('../Toolbar/Toolbar', () => ({
14
+ default: vi.fn(() => <div id="Portal" />),
15
+ }));
14
16
 
15
17
  describe('ChangePassword', () => {
16
18
  it('renders a change password component', () => {
@@ -18,7 +18,9 @@ const userSchema = {
18
18
  loading: false,
19
19
  };
20
20
 
21
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
21
+ vi.mock('../Toolbar/Toolbar', () => ({
22
+ default: vi.fn(() => <div id="Portal" />),
23
+ }));
22
24
 
23
25
  describe('PersonalInformation', () => {
24
26
  it('renders a personal information component', async () => {
@@ -8,14 +8,18 @@ import PersonalPreferences from './PersonalPreferences';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
11
+ vi.mock('../Toolbar/Toolbar', () => ({
12
+ default: vi.fn(() => <div id="Portal" />),
13
+ }));
12
14
 
13
- jest.mock('@plone/volto/components/manage/Form');
14
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
15
- beforeAll(
16
- async () =>
17
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
18
- );
15
+ vi.mock('@plone/volto/components/manage/Form');
16
+ vi.mock('@plone/volto/helpers/Loadable/Loadable');
17
+ beforeAll(async () => {
18
+ const { __setLoadables } = await import(
19
+ '@plone/volto/helpers/Loadable/Loadable'
20
+ );
21
+ await __setLoadables();
22
+ });
19
23
 
20
24
  describe('PersonalPreferences', () => {
21
25
  it('renders a personal preferences component', () => {
@@ -9,9 +9,12 @@ import Rules from './Rules';
9
9
  const middlewares = [thunk];
10
10
  const mockStore = configureMockStore(middlewares);
11
11
 
12
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
13
-
14
- jest.mock('../Toolbar/More', () => jest.fn(() => <div className="More" />));
12
+ vi.mock('../Toolbar/Toolbar', () => ({
13
+ default: vi.fn(() => <div id="Portal" />),
14
+ }));
15
+ vi.mock('../Toolbar/More', () => ({
16
+ default: vi.fn(() => <div className="More" />),
17
+ }));
15
18
 
16
19
  describe('Rules', () => {
17
20
  it('renders rules object control', () => {
@@ -10,7 +10,9 @@ import Sharing from './Sharing';
10
10
 
11
11
  const mockStore = configureStore();
12
12
 
13
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
13
+ vi.mock('../Toolbar/Toolbar', () => ({
14
+ default: vi.fn(() => <div id="Portal" />),
15
+ }));
14
16
 
15
17
  describe('Sharing', () => {
16
18
  it('renders a sharing component', () => {
@@ -110,11 +110,11 @@ describe('ObjectBrowserNav', () => {
110
110
  const baseProps = {
111
111
  currentSearchResults,
112
112
  isSelectable: () => true,
113
- handleClickOnItem: jest.fn(),
114
- handleDoubleClickOnItem: jest.fn(),
113
+ handleClickOnItem: vi.fn(),
114
+ handleDoubleClickOnItem: vi.fn(),
115
115
  mode: 'link',
116
116
  view: 'list',
117
- navigateTo: jest.fn(),
117
+ navigateTo: vi.fn(),
118
118
  };
119
119
 
120
120
  it('renders a view image component', () => {
@@ -6,13 +6,12 @@ import { waitFor, render } from '@testing-library/react';
6
6
 
7
7
  import More from './More';
8
8
 
9
- jest.mock('../../manage/Display/Display', () =>
10
- jest.fn(() => <div id="display-select" />),
11
- );
12
-
13
- jest.mock('../../manage/Workflow/Workflow', () =>
14
- jest.fn(() => <div id="state-select" />),
15
- );
9
+ vi.mock('../../manage/Display/Display', () => ({
10
+ default: vi.fn(() => <div id="display-select" />),
11
+ }));
12
+ vi.mock('../../manage/Workflow/Workflow', () => ({
13
+ default: vi.fn(() => <div id="state-select" />),
14
+ }));
16
15
 
17
16
  const mockStore = configureStore();
18
17
 
@@ -18,7 +18,7 @@ const store = mockStore({
18
18
  },
19
19
  });
20
20
 
21
- global.console.error = jest.fn();
21
+ global.console.error = vi.fn();
22
22
 
23
23
  describe('UniversalLink', () => {
24
24
  it('renders a UniversalLink component with internal link', () => {
@@ -8,11 +8,21 @@ import ArrayWidget from './ArrayWidget';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
12
- beforeAll(
13
- async () =>
14
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
15
- );
11
+ vi.mock('@plone/volto/helpers/Loadable/Loadable');
12
+
13
+ // Mock react-sortable-hoc to prevent the container error
14
+ vi.mock('react-sortable-hoc', () => ({
15
+ ...vi.importActual('react-sortable-hoc'),
16
+ SortableContainer: (component) => component,
17
+ SortableElement: (component) => component,
18
+ }));
19
+
20
+ beforeAll(async () => {
21
+ const { __setLoadables } = await import(
22
+ '@plone/volto/helpers/Loadable/Loadable'
23
+ );
24
+ await __setLoadables();
25
+ });
16
26
 
17
27
  test('renders an array widget component', async () => {
18
28
  const store = mockStore({
@@ -27,6 +37,7 @@ test('renders an array widget component', async () => {
27
37
  },
28
38
  },
29
39
  });
40
+
30
41
  const component = renderer.create(
31
42
  <Provider store={store}>
32
43
  <ArrayWidget
@@ -38,6 +49,7 @@ test('renders an array widget component', async () => {
38
49
  />
39
50
  </Provider>,
40
51
  );
52
+
41
53
  await waitFor(() => {});
42
54
  expect(component.toJSON()).toMatchSnapshot();
43
55
  });
@@ -83,5 +95,6 @@ test("No 'No value' option when default value is 0", async () => {
83
95
  container.querySelector('.react-select__dropdown-indicator'),
84
96
  { button: 0 },
85
97
  );
98
+
86
99
  expect(container).toMatchSnapshot();
87
100
  });
@@ -7,11 +7,13 @@ import CheckboxGroupWidget from './CheckboxGroupWidget';
7
7
 
8
8
  const mockStore = configureStore();
9
9
 
10
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
11
- beforeAll(
12
- async () =>
13
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
14
- );
10
+ vi.mock('@plone/volto/helpers/Loadable/Loadable');
11
+ beforeAll(async () => {
12
+ const { __setLoadables } = await import(
13
+ '@plone/volto/helpers/Loadable/Loadable'
14
+ );
15
+ await __setLoadables();
16
+ });
15
17
 
16
18
  test('renders a checkbox group widget component', async () => {
17
19
  const store = mockStore({
@@ -6,11 +6,14 @@ import { waitFor, render, screen } from '@testing-library/react';
6
6
 
7
7
  const mockStore = configureStore();
8
8
 
9
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
10
- beforeAll(
11
- async () =>
12
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
13
- );
9
+ vi.mock('@plone/volto/helpers/Loadable/Loadable');
10
+
11
+ beforeAll(async () => {
12
+ const { __setLoadables } = await import(
13
+ '@plone/volto/helpers/Loadable/Loadable'
14
+ );
15
+ await __setLoadables();
16
+ });
14
17
 
15
18
  test('renders a datetime widget component', async () => {
16
19
  const store = mockStore({
@@ -19,6 +22,7 @@ test('renders a datetime widget component', async () => {
19
22
  messages: {},
20
23
  },
21
24
  });
25
+
22
26
  const isoDate = new Date('2019-10-21').toISOString();
23
27
  const { container } = render(
24
28
  <Provider store={store}>
@@ -28,20 +32,24 @@ test('renders a datetime widget component', async () => {
28
32
  fieldSet="default"
29
33
  onChange={() => {}}
30
34
  value={isoDate}
35
+ showTime={true}
31
36
  />
32
37
  </Provider>,
33
38
  );
39
+
34
40
  await waitFor(() => screen.getByText(/My field/));
41
+ await waitFor(() => screen.getByPlaceholderText('Time'));
35
42
  expect(container).toMatchSnapshot();
36
43
  });
37
44
 
38
- test('datetime widget converts UTC date and adapt to local datetime', async () => {
45
+ test('datetime widget converts UTC date and adapts to local datetime', async () => {
39
46
  const store = mockStore({
40
47
  intl: {
41
48
  locale: 'en',
42
49
  messages: {},
43
50
  },
44
51
  });
52
+
45
53
  const date = '2020-02-10T15:01:00.000Z';
46
54
  const { container } = render(
47
55
  <Provider store={store}>
@@ -50,9 +58,12 @@ test('datetime widget converts UTC date and adapt to local datetime', async () =
50
58
  title="My field"
51
59
  onChange={() => {}}
52
60
  value={date}
61
+ showTime={true}
53
62
  />
54
63
  </Provider>,
55
64
  );
65
+
56
66
  await waitFor(() => screen.getByText(/My field/));
67
+ await waitFor(() => screen.getByPlaceholderText('Time'));
57
68
  expect(container).toMatchSnapshot();
58
69
  });
@@ -5,7 +5,7 @@
5
5
 
6
6
  import React from 'react';
7
7
  import PropTypes from 'prop-types';
8
- import { Button, Image, Dimmer } from 'semantic-ui-react';
8
+ import { Button, Dimmer } from 'semantic-ui-react';
9
9
  import { readAsDataURL } from 'promise-file-reader';
10
10
  import { injectIntl } from 'react-intl';
11
11
  import deleteSVG from '@plone/volto/icons/delete.svg';
@@ -13,6 +13,7 @@ import Icon from '@plone/volto/components/theme/Icon/Icon';
13
13
  import Toast from '@plone/volto/components/manage/Toast/Toast';
14
14
  import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
15
15
  import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
16
+ import Image from '@plone/volto/components/theme/Image/Image';
16
17
  import loadable from '@loadable/component';
17
18
  import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
18
19
  import { validateFileUploadSize } from '@plone/volto/helpers/FormValidation/FormValidation';
@@ -172,9 +173,8 @@ const FileWidget = (props) => {
172
173
  {isDragActive && <Dimmer active></Dimmer>}
173
174
  {fileType ? (
174
175
  <Image
175
- className="image-preview"
176
+ className="image-preview small ui image"
176
177
  id={`field-${id}-image`}
177
- size="small"
178
178
  src={imgsrc}
179
179
  />
180
180
  ) : (
@@ -2,21 +2,36 @@ import React from 'react';
2
2
  import { Provider } from 'react-intl-redux';
3
3
  import { render, waitFor } from '@testing-library/react';
4
4
  import configureStore from 'redux-mock-store';
5
-
6
5
  import FileWidget from './FileWidget';
7
6
 
8
- jest.spyOn(global.Date, 'now').mockImplementation(() => '0');
7
+ vi.spyOn(global.Date, 'now').mockImplementation(() => 1234567890);
9
8
 
10
9
  const mockStore = configureStore();
11
10
 
11
+ const createStore = () =>
12
+ mockStore({
13
+ intl: {
14
+ locale: 'en',
15
+ messages: {},
16
+ },
17
+ });
18
+
12
19
  describe('FileWidget', () => {
13
- test('renders an empty file widget component', async () => {
14
- const store = mockStore({
15
- intl: {
16
- locale: 'en',
17
- messages: {},
20
+ beforeEach(() => {
21
+ vi.clearAllTimers();
22
+ Object.defineProperty(global.Image.prototype, 'complete', {
23
+ get() {
24
+ return true;
18
25
  },
19
26
  });
27
+ });
28
+
29
+ afterEach(() => {
30
+ vi.clearAllMocks();
31
+ });
32
+
33
+ test('renders an empty file widget component', async () => {
34
+ const store = createStore();
20
35
 
21
36
  const { container } = render(
22
37
  <Provider store={store}>
@@ -29,16 +44,18 @@ describe('FileWidget', () => {
29
44
  </Provider>,
30
45
  );
31
46
 
32
- await waitFor(() => {});
47
+ await waitFor(
48
+ () => {
49
+ expect(container.querySelector('.file-widget-dropzone')).toBeTruthy();
50
+ },
51
+ { timeout: 1000 },
52
+ );
53
+
33
54
  expect(container).toMatchSnapshot();
34
55
  });
56
+
35
57
  test('renders a file widget component with value', async () => {
36
- const store = mockStore({
37
- intl: {
38
- locale: 'en',
39
- messages: {},
40
- },
41
- });
58
+ const store = createStore();
42
59
 
43
60
  const { container } = render(
44
61
  <Provider store={store}>
@@ -57,16 +74,22 @@ describe('FileWidget', () => {
57
74
  </Provider>,
58
75
  );
59
76
 
60
- await waitFor(() => {});
77
+ await waitFor(
78
+ () => {
79
+ const dropzone = container.querySelector('.file-widget-dropzone');
80
+ const preview = container.querySelector('.image-preview');
81
+ const filename = container.querySelector('.field-file-name');
82
+
83
+ return dropzone && preview && filename;
84
+ },
85
+ { timeout: 1000 },
86
+ );
87
+
61
88
  expect(container).toMatchSnapshot();
62
89
  });
90
+
63
91
  test('renders a file widget component with value in raw data', async () => {
64
- const store = mockStore({
65
- intl: {
66
- locale: 'en',
67
- messages: {},
68
- },
69
- });
92
+ const store = createStore();
70
93
 
71
94
  const { container } = render(
72
95
  <Provider store={store}>
@@ -85,7 +108,16 @@ describe('FileWidget', () => {
85
108
  </Provider>,
86
109
  );
87
110
 
88
- await waitFor(() => {});
111
+ await waitFor(
112
+ () => {
113
+ const dropzone = container.querySelector('.file-widget-dropzone');
114
+ const filename = container.querySelector('.field-file-name');
115
+
116
+ return dropzone && filename;
117
+ },
118
+ { timeout: 1000 },
119
+ );
120
+
89
121
  expect(container).toMatchSnapshot();
90
122
  });
91
123
  });
@@ -16,13 +16,14 @@ test('renders a number widget component', () => {
16
16
  });
17
17
  const component = renderer.create(
18
18
  <Provider store={store}>
19
- <NumberWidget
20
- id="my-field"
21
- title="My field"
22
- fieldSet="default"
23
- onChange={() => {}}
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();
@@ -12,7 +12,7 @@ import isArray from 'lodash/isArray';
12
12
  import isEmpty from 'lodash/isEmpty';
13
13
  import remove from 'lodash/remove';
14
14
  import { connect } from 'react-redux';
15
- import { Image, Label, Popup, Button } from 'semantic-ui-react';
15
+ import { Label, Popup, Button } from 'semantic-ui-react';
16
16
  import {
17
17
  flattenToAppURL,
18
18
  isInternalURL,
@@ -33,6 +33,7 @@ import homeSVG from '@plone/volto/icons/home.svg';
33
33
  import aheadSVG from '@plone/volto/icons/ahead.svg';
34
34
  import blankSVG from '@plone/volto/icons/blank.svg';
35
35
  import { withRouter } from 'react-router';
36
+ import Image from '@plone/volto/components/theme/Image/Image';
36
37
 
37
38
  const messages = defineMessages({
38
39
  placeholder: {
@@ -131,7 +132,7 @@ export class ObjectBrowserWidgetComponent extends Component {
131
132
  <div className="item-title">
132
133
  {includes(config.settings.imageObjects, item['@type']) ? (
133
134
  <Image
134
- size="small"
135
+ className="small ui image"
135
136
  src={`${item['@id']}/@@images/image/thumb`}
136
137
  />
137
138
  ) : (