@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.
Files changed (148) hide show
  1. package/.eslintignore +1 -0
  2. package/.eslintrc +2 -0
  3. package/CHANGELOG.md +46 -2
  4. package/package.json +14 -7
  5. package/src/actions/actions/actions.test.js +3 -3
  6. package/src/actions/addons/addons.test.js +15 -12
  7. package/src/actions/aliases/aliases.test.js +1 -1
  8. package/src/actions/querystring/querystring.test.js +2 -2
  9. package/src/actions/types/types.test.js +1 -1
  10. package/src/components/manage/Actions/Actions.test.jsx +5 -1
  11. package/src/components/manage/Add/Add.jsx +22 -20
  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 +1 -0
  15. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +48 -16
  16. package/src/components/manage/Blocks/Block/Edit.jsx +2 -1
  17. package/src/components/manage/Blocks/Block/Settings.test.jsx +5 -1
  18. package/src/components/manage/Blocks/Block/StyleWrapper.jsx +11 -3
  19. package/src/components/manage/Blocks/Description/View.test.jsx +1 -1
  20. package/src/components/manage/Blocks/HTML/Edit.test.jsx +12 -5
  21. package/src/components/manage/Blocks/HTML/View.test.jsx +1 -1
  22. package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +6 -2
  23. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +8 -1
  24. package/src/components/manage/Blocks/Listing/View.test.jsx +3 -1
  25. package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +5 -1
  26. package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +13 -7
  27. package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +12 -6
  28. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.test.jsx +11 -1
  29. package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +5 -1
  30. package/src/components/manage/ConditionalLink/ConditionalLink.test.tsx +109 -0
  31. package/src/components/manage/ConditionalLink/ConditionalLink.tsx +36 -0
  32. package/src/components/manage/Contents/Contents.test.jsx +29 -13
  33. package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +5 -1
  34. package/src/components/manage/Contents/ContentsRenameModal.test.jsx +5 -1
  35. package/src/components/manage/Contents/ContentsTagsModal.test.jsx +5 -1
  36. package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +5 -1
  37. package/src/components/manage/Contents/__mocks__/index.tsx +16 -0
  38. package/src/components/manage/Contents/__mocks__/index.vitest.tsx +5 -0
  39. package/src/components/manage/Controlpanels/AddonsControlpanel.test.jsx +28 -3
  40. package/src/components/manage/Controlpanels/Aliases.test.jsx +35 -3
  41. package/src/components/manage/Controlpanels/ContentType.test.jsx +29 -3
  42. package/src/components/manage/Controlpanels/ContentTypeLayout.test.jsx +4 -2
  43. package/src/components/manage/Controlpanels/ContentTypes.test.jsx +25 -2
  44. package/src/components/manage/Controlpanels/Controlpanel.test.jsx +37 -6
  45. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +47 -3
  46. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.test.jsx +15 -9
  47. package/src/components/manage/Controlpanels/ModerateComments.test.jsx +31 -5
  48. package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +13 -4
  49. package/src/components/manage/Controlpanels/Rules/ConfigureRule.test.jsx +9 -5
  50. package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +12 -4
  51. package/src/components/manage/Controlpanels/Rules/Rules.test.jsx +7 -3
  52. package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +33 -4
  53. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +3 -1
  54. package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +15 -9
  55. package/src/components/manage/Delete/Delete.test.jsx +45 -4
  56. package/src/components/manage/Diff/Diff.test.jsx +15 -6
  57. package/src/components/manage/Diff/DiffField.test.jsx +12 -6
  58. package/src/components/manage/Display/Display.test.jsx +17 -6
  59. package/src/components/manage/Edit/Edit.test.jsx +11 -3
  60. package/src/components/manage/Form/BlockDataForm.test.jsx +5 -1
  61. package/src/components/manage/Form/Form.test.jsx +5 -1
  62. package/src/components/manage/Form/InlineForm.test.jsx +5 -1
  63. package/src/components/manage/Form/ModalForm.test.jsx +5 -1
  64. package/src/components/manage/Form/__mocks__/index.tsx +17 -0
  65. package/src/components/manage/Form/__mocks__/index.vitest.tsx +73 -0
  66. package/src/components/manage/History/History.test.jsx +3 -1
  67. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +6 -4
  68. package/src/components/manage/MaybeWrap/MaybeWrap.tsx +15 -0
  69. package/src/components/manage/Multilingual/ManageTranslations.test.jsx +3 -2
  70. package/src/components/manage/Preferences/ChangePassword.test.jsx +9 -2
  71. package/src/components/manage/Preferences/PersonalInformation.test.jsx +3 -1
  72. package/src/components/manage/Preferences/PersonalPreferences.test.jsx +20 -7
  73. package/src/components/manage/Rules/Rules.test.jsx +6 -3
  74. package/src/components/manage/Sharing/Sharing.test.jsx +3 -1
  75. package/src/components/manage/Sidebar/ObjectBrowserNav.test.jsx +3 -3
  76. package/src/components/manage/Toolbar/More.test.jsx +6 -7
  77. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +196 -14
  78. package/src/components/manage/UniversalLink/UniversalLink.tsx +214 -0
  79. package/src/components/manage/Widgets/ArrayWidget.test.jsx +22 -5
  80. package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +12 -5
  81. package/src/components/manage/Widgets/DatetimeWidget.test.jsx +21 -6
  82. package/src/components/manage/Widgets/ImageWidget.jsx +5 -2
  83. package/src/components/manage/Widgets/NumberWidget.test.jsx +8 -7
  84. package/src/components/manage/Widgets/ObjectListWidget.jsx +11 -1
  85. package/src/components/manage/Widgets/ObjectListWidget.test.jsx +18 -8
  86. package/src/components/manage/Widgets/ObjectWidget.test.jsx +5 -1
  87. package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +12 -5
  88. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +12 -6
  89. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +43 -41
  90. package/src/components/manage/Widgets/SchemaWidget.test.jsx +12 -5
  91. package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +12 -5
  92. package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +12 -6
  93. package/src/components/manage/Widgets/SelectWidget.test.jsx +12 -6
  94. package/src/components/manage/Widgets/TimeWidget.test.jsx +13 -5
  95. package/src/components/manage/Widgets/TokenWidget.test.jsx +12 -6
  96. package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +18 -9
  97. package/src/components/manage/Widgets/__mocks__/index.tsx +16 -0
  98. package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +41 -0
  99. package/src/components/manage/Workflow/Workflow.test.jsx +17 -7
  100. package/src/components/theme/App/App.test.jsx +21 -17
  101. package/src/components/theme/AppExtras/AppExtras.test.jsx +6 -6
  102. package/src/components/theme/Comments/CommentEditModal.test.jsx +5 -1
  103. package/src/components/theme/Comments/Comments.test.jsx +29 -12
  104. package/src/components/theme/ContactForm/ContactForm.test.jsx +8 -4
  105. package/src/components/theme/Header/Header.test.jsx +19 -13
  106. package/src/components/theme/Logout/Logout.test.jsx +1 -1
  107. package/src/components/theme/PasswordReset/PasswordReset.test.jsx +10 -1
  108. package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +5 -1
  109. package/src/components/theme/Register/Register.test.jsx +5 -1
  110. package/src/components/theme/Search/Search.test.jsx +6 -4
  111. package/src/components/theme/TsTest/TsTest.test.tsx +0 -1
  112. package/src/components/theme/View/EventDatesInfo.test.jsx +12 -5
  113. package/src/components/theme/View/EventView.test.jsx +12 -5
  114. package/src/components/theme/View/ListingView.test.jsx +2 -0
  115. package/src/components/theme/View/SummaryView.test.jsx +10 -0
  116. package/src/components/theme/View/TabularView.test.jsx +1 -0
  117. package/src/components/theme/View/View.test.jsx +42 -23
  118. package/src/helpers/Api/Api.plone.rest.test.js +11 -9
  119. package/src/helpers/Api/Api.test.js +11 -14
  120. package/src/helpers/AsyncConnect/AsyncConnect.test.jsx +145 -189
  121. package/src/helpers/AuthToken/AuthToken.test.js +60 -22
  122. package/src/helpers/Blocks/Blocks.test.js +1 -1
  123. package/src/helpers/Html/Html.test.jsx +32 -28
  124. package/src/helpers/Loadable/__mocks__/Loadable.jsx +16 -1
  125. package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +39 -0
  126. package/src/middleware/Api.test.js +47 -0
  127. package/src/middleware/api.js +1 -1
  128. package/src/middleware/storeProtectLoadUtils.test.js +90 -78
  129. package/test-setup-globals-vitest.js +46 -0
  130. package/tsconfig.declarations.json +12 -1
  131. package/tsconfig.json +2 -1
  132. package/types/components/manage/ConditionalLink/ConditionalLink.d.ts +11 -15
  133. package/types/components/manage/Contents/__mocks__/index.vitest.d.ts +2 -0
  134. package/types/components/manage/Form/__mocks__/index.vitest.d.ts +8 -0
  135. package/types/components/manage/MaybeWrap/MaybeWrap.d.ts +7 -5
  136. package/types/components/manage/UniversalLink/UniversalLink.d.ts +54 -20
  137. package/types/components/manage/Widgets/__mocks__/index.vitest.d.ts +33 -0
  138. package/types/helpers/Loadable/__mocks__/Loadable.vitest.d.ts +3 -0
  139. package/types/react-router-hash-link.d.ts +12 -0
  140. package/types/routes.d.ts +4 -0
  141. package/types/server.d.ts +1 -1
  142. package/vite-plugins/svg.mjs +81 -0
  143. package/vitest.config.mjs +77 -0
  144. package/src/components/manage/ConditionalLink/ConditionalLink.jsx +0 -27
  145. package/src/components/manage/ConditionalLink/ConditionalLink.test.jsx +0 -30
  146. package/src/components/manage/MaybeWrap/MaybeWrap.jsx +0 -9
  147. package/src/components/manage/UniversalLink/UniversalLink.jsx +0 -154
  148. package/src/components/manage/Widgets/FileWidget.test.jsx +0 -91
package/.eslintignore CHANGED
@@ -1 +1,2 @@
1
1
  /types/
2
+ !types/react-router-hash-link.d.ts
package/.eslintrc CHANGED
@@ -91,5 +91,7 @@
91
91
  "jest": true,
92
92
  "socket": true,
93
93
  "webpackIsomorphicTools": true,
94
+ "vitest":true,
95
+ "vi":true
94
96
  },
95
97
  }
package/CHANGELOG.md CHANGED
@@ -17,6 +17,50 @@ myst:
17
17
 
18
18
  <!-- towncrier release notes start -->
19
19
 
20
+ ## 19.0.0-alpha.1 (2025-05-16)
21
+
22
+ ### Feature
23
+
24
+ - Volto core has migrated from Jest to Vitest as its unit test runner. @Abhishek-17h [#6326](https://github.com/plone/volto/issues/6326)
25
+ - Refactor the UniversalLink component using typescript.
26
+ Use union types for deciding between href or item.
27
+ Modify tsconfig, include types located in `types` folder, otherwise d.ts files will noch be recognized in .tsx files, e.g. inside components. I need this for the `react-router-hash-link` package, that we use in the UniversalLink component. The specific file is `/types/react-router-hash-link.d.ts`.
28
+ Modify lint-staged.config.js to exclude d.ts files.
29
+ Use newest version of classnames (with types).
30
+ Create tests and negative tests for optimization with React.memo (add render counter for testing this behavior)
31
+
32
+ @tomschall [#6826](https://github.com/plone/volto/issues/6826)
33
+ - `ConditionalLink` in TypeScript. @sneridagh [#6959](https://github.com/plone/volto/issues/6959)
34
+ - Allow `object_list` widget to receive a `schemaName` prop, mapped to an utility. @sneridagh [#7007](https://github.com/plone/volto/issues/7007)
35
+ - Added current evaluated `querystring` as a parameter in expander's `querystring` key when it's a function. @sneridagh [#7012](https://github.com/plone/volto/issues/7012)
36
+ - Move `MaybeWrap` to TypeScript. @sneridagh [#7029](https://github.com/plone/volto/issues/7029)
37
+ - Rename `vitest.config.ts` to `vitest.config.mjs` for allowing it to be loaded from add-ons. @sneridagh [#7035](https://github.com/plone/volto/issues/7035)
38
+ - Added `contained` class if `isContainer` prop is passed (from containers). @sneridagh [#7043](https://github.com/plone/volto/issues/7043)
39
+ - The `Add` component can now optionally receive `initialFormData` from the `CreateTranslation` component. This makes it possible for a custom `CreateTranslation` implementation to fully control the initial translation. @Tishasoumya-02 [#7073](https://github.com/plone/volto/issues/7073)
40
+
41
+ ### Bugfix
42
+
43
+ - Fixed broken tests in add-ons in Volto 18.12.0. @Abhishek-17h [#6989](https://github.com/plone/volto/issues/6989)
44
+ - Add support for both Vitest and Jest in `__mocks__` folders of Volto core. Add-on tests using Jest relies on them. @Abhishek-17h [#7000](https://github.com/plone/volto/issues/7000)
45
+ - Added missing dependency for `sgvo`. Fixed `svgo` library loading in `./vite-plugins/svg.js`. @sneridagh [#7035](https://github.com/plone/volto/issues/7035)
46
+ - Rename `./vite-plugins/svg.js` to proper extension `vite-plugins/svg.mjs`. @sneridagh [#7035](https://github.com/plone/volto/issues/7035)
47
+ - Fixed stuck states in the Image Upload Widget by resetting uploading after failed size validation and dragging after image deletion or drag events, ensuring proper functionality and user feedback. [#7045](https://github.com/plone/volto/issues/7045)
48
+ - Improve typings in ConditionalLink component, add TS tests to catch the bad typings. @sneridagh [#7057](https://github.com/plone/volto/issues/7057)
49
+
50
+ ### Internal
51
+
52
+ - Fixed types of #6826 in build:types. @sneridagh
53
+
54
+ ### Documentation
55
+
56
+ - Pin plone-sphinx-theme to prepare for PLIP 4097. See https://github.com/plone/Products.CMFPlone/issues/4097. @stevepiercy [#7015](https://github.com/plone/volto/issues/7015)
57
+ - Corrected Redux-related docs.
58
+ Better word wrapping in Redux-related docs.
59
+ Added link to Redux development add-on for Firefox.
60
+ @silviubogan [#7023](https://github.com/plone/volto/issues/7023)
61
+ - Updated documentation code example from Jest to Vitest in the "Bundle size optimization" chapter. @Abhishek-17h [#7024](https://github.com/plone/volto/issues/7024)
62
+ - Add version added admonition to Upgrade Guide for migrating grid blocks, and link from Upgrade Guide to Grid Block documentation. @ionlizarazu [#7027](https://github.com/plone/volto/issues/7027)
63
+
20
64
  ## 19.0.0-alpha.0 (2025-04-12)
21
65
 
22
66
  ### Breaking
@@ -67,7 +111,7 @@ myst:
67
111
  - Add Russian translation in Volto. @toropok [#6874](https://github.com/plone/volto/issues/6874)
68
112
  - Enhance the `ImageInput` component to only accept image files. [@jnptk] [#6926](https://github.com/plone/volto/issues/6926)
69
113
  - Fix translations default of ContentsDeleteModal: 'linkintegrity: delete' -> 'delete' if no link to break. @ksuess [#6964](https://github.com/plone/volto/issues/6964)
70
- - Use Plone 6.1.1 final. @sneridagh
114
+ - Use Plone 6.1.1 final. @sneridagh
71
115
 
72
116
  ### Bugfix
73
117
 
@@ -1946,7 +1990,7 @@ myst:
1946
1990
  - (FIX): put padding so the text is not clipped #5305 @dobri1408 [#5305](https://github.com/plone/volto/issues/5305)
1947
1991
  - Fix compare translations view @sneridagh [#5327](https://github.com/plone/volto/issues/5327)
1948
1992
  - Fix DatetimeWidget on FF, the button default if no type is set is sending the form. @sneridagh
1949
- See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#formmethod [#5343](https://github.com/plone/volto/issues/5343)
1993
+ See https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/button#formmethod [#5343](https://github.com/plone/volto/issues/5343)
1950
1994
 
1951
1995
  ### Internal
1952
1996
 
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "19.0.0-alpha.0",
12
+ "version": "19.0.0-alpha.1",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -150,7 +150,7 @@
150
150
  "@loadable/component": "5.14.1",
151
151
  "@loadable/server": "5.14.0",
152
152
  "@redux-devtools/extension": "^3.3.0",
153
- "classnames": "2.2.6",
153
+ "classnames": "2.5.1",
154
154
  "connected-react-router": "6.8.0",
155
155
  "debug": "4.3.2",
156
156
  "decorate-component-with-props": "1.2.1",
@@ -236,9 +236,9 @@
236
236
  "url": "^0.11.3",
237
237
  "use-deep-compare-effect": "1.8.1",
238
238
  "uuid": "^8.3.2",
239
- "@plone/volto-slate": "19.0.0-alpha.0",
240
- "@plone/scripts": "4.0.0-alpha.0",
241
- "@plone/registry": "3.0.0-alpha.2"
239
+ "@plone/registry": "3.0.0-alpha.3",
240
+ "@plone/volto-slate": "19.0.0-alpha.1",
241
+ "@plone/scripts": "4.0.0-alpha.1"
242
242
  },
243
243
  "devDependencies": {
244
244
  "@babel/core": "^7.0.0",
@@ -276,6 +276,7 @@
276
276
  "@types/jest": "^29.5.8",
277
277
  "@types/loadable__component": "^5.13.9",
278
278
  "@types/lodash": "^4.14.201",
279
+ "@types/node": "^22.13.0",
279
280
  "@types/react": "^18",
280
281
  "@types/react-dom": "^18",
281
282
  "@types/react-router-dom": "^5.3.3",
@@ -283,6 +284,8 @@
283
284
  "@types/uuid": "^9.0.2",
284
285
  "@typescript-eslint/eslint-plugin": "^7.7.0",
285
286
  "@typescript-eslint/parser": "^7.7.0",
287
+ "@vitejs/plugin-react": "^4.3.4",
288
+ "@vitest/ui": "^2.1.8",
286
289
  "autoprefixer": "10.4.8",
287
290
  "axe-core": "4.4.2",
288
291
  "babel-loader": "9.1.0",
@@ -315,6 +318,7 @@
315
318
  "jest": "26.6.3",
316
319
  "jest-environment-jsdom": "^26",
317
320
  "jest-file": "1.0.0",
321
+ "jiti": "^2.4.2",
318
322
  "jsdom": "^16.7.0",
319
323
  "jsonwebtoken": "9.0.0",
320
324
  "less": "3.11.1",
@@ -345,6 +349,7 @@
345
349
  "stylelint-config-idiomatic-order": "10.0.0",
346
350
  "stylelint-prettier": "5.0.0",
347
351
  "svg-loader": "0.0.2",
352
+ "svgo": "^3.0.0",
348
353
  "svgo-loader": "3.0.3",
349
354
  "terser-webpack-plugin": "5.3.6",
350
355
  "tmp": "0.2.1",
@@ -352,13 +357,14 @@
352
357
  "ts-loader": "9.4.4",
353
358
  "typescript": "^5.7.3",
354
359
  "use-trace-update": "1.3.2",
360
+ "vitest": "^3.0.4",
355
361
  "wait-on": "6.0.0",
356
362
  "webpack": "5.90.1",
357
363
  "webpack-bundle-analyzer": "4.10.1",
358
364
  "webpack-dev-server": "4.11.1",
359
365
  "webpack-node-externals": "3.0.0",
360
366
  "why": "0.6.2",
361
- "@plone/types": "2.0.0-alpha.1",
367
+ "@plone/types": "2.0.0-alpha.3",
362
368
  "@plone/volto-coresandbox": "1.0.0"
363
369
  },
364
370
  "volta": {
@@ -370,10 +376,11 @@
370
376
  "start:coresandbox": "make build-deps && ADDONS=coresandbox razzle start",
371
377
  "build": "make build-deps && razzle build --noninteractive",
372
378
  "build:types": "tsc --project tsconfig.declarations.json",
379
+ "vitest": "vitest",
380
+ "coverage": "vitest run --coverage",
373
381
  "test": "razzle test --maxWorkers=50%",
374
382
  "test:ci": "CI=true NODE_ICU_DATA=node_modules/full-icu razzle test",
375
383
  "test:husky": "CI=true yarn test --bail --findRelatedTests",
376
- "test:debug": "node --inspect node_modules/.bin/jest --runInBand",
377
384
  "start:prod": "NODE_ENV=production node build/server.js",
378
385
  "prettier": "prettier --single-quote --check '{src,cypress}/**/*.{js,jsx,ts,tsx}' --check '*.js'",
379
386
  "prettier:fix": "prettier --single-quote --write '{src,cypress}/**/*.{js,jsx,ts,tsx}' --write '*.js'",
@@ -7,9 +7,9 @@ describe('Actions action', () => {
7
7
  const url = 'http://localhost';
8
8
  const action = listActions(url);
9
9
 
10
- expect(action.type).toEqual(LIST_ACTIONS);
11
- expect(action.request.op).toEqual('get');
12
- expect(action.request.path).toEqual(`${url}/@actions`);
10
+ expect(action.type).toBe(LIST_ACTIONS);
11
+ expect(action.request.op).toBe('get');
12
+ expect(action.request.path).toBe(`${url}/@actions`);
13
13
  });
14
14
  });
15
15
  });
@@ -16,35 +16,38 @@ describe('Addons action', () => {
16
16
  it('should create an action to install an addon', () => {
17
17
  const id = 'plone.app.example';
18
18
  const action = installAddon(id);
19
- expect(action.type).toEqual(INSTALL_ADDON);
20
- expect(action.request.op).toEqual('post');
21
- expect(action.request.path).toEqual(`/@addons/${id}/install`);
19
+ expect(action.type).toBe(INSTALL_ADDON);
20
+ expect(action.request.op).toBe('post');
21
+ expect(action.request.path).toBe(`/@addons/${id}/install`);
22
22
  });
23
23
  });
24
+
24
25
  describe('uninstallAddon', () => {
25
26
  it('should create an action to uninstall an addon', () => {
26
27
  const id = 'plone.app.example';
27
28
  const action = uninstallAddon(id);
28
- expect(action.type).toEqual(UNINSTALL_ADDON);
29
- expect(action.request.op).toEqual('post');
30
- expect(action.request.path).toEqual(`/@addons/${id}/uninstall`);
29
+ expect(action.type).toBe(UNINSTALL_ADDON);
30
+ expect(action.request.op).toBe('post');
31
+ expect(action.request.path).toBe(`/@addons/${id}/uninstall`);
31
32
  });
32
33
  });
34
+
33
35
  describe('upgradeAddon', () => {
34
36
  it('should create an action to upgrade an addon', () => {
35
37
  const id = 'plone.app.example';
36
38
  const action = upgradeAddon(id);
37
- expect(action.type).toEqual(UPGRADE_ADDON);
38
- expect(action.request.op).toEqual('post');
39
- expect(action.request.path).toEqual(`/@addons/${id}/upgrade`);
39
+ expect(action.type).toBe(UPGRADE_ADDON);
40
+ expect(action.request.op).toBe('post');
41
+ expect(action.request.path).toBe(`/@addons/${id}/upgrade`);
40
42
  });
41
43
  });
44
+
42
45
  describe('listAddons', () => {
43
46
  it('should create an action to list all addons', () => {
44
47
  const action = listAddons();
45
- expect(action.type).toEqual(LIST_ADDONS);
46
- expect(action.request.op).toEqual('get');
47
- expect(action.request.path).toEqual(`/@addons`);
48
+ expect(action.type).toBe(LIST_ADDONS);
49
+ expect(action.request.op).toBe('get');
50
+ expect(action.request.path).toBe(`/@addons`);
48
51
  });
49
52
  });
50
53
  });
@@ -1,5 +1,4 @@
1
1
  import { getAliases, addAliases, removeAliases } from './aliases';
2
-
3
2
  import {
4
3
  GET_ALIASES,
5
4
  ADD_ALIASES,
@@ -18,6 +17,7 @@ describe('Aliases action', () => {
18
17
  );
19
18
  });
20
19
  });
20
+
21
21
  describe('addAliases', () => {
22
22
  it('should create an action to add aliases', () => {
23
23
  const url = '/news';
@@ -5,7 +5,7 @@ describe('Querystring action', () => {
5
5
  describe('getQuerystring', () => {
6
6
  it('should create an action to get the querystring config', () => {
7
7
  const getState = () => ({});
8
- const dispatch = jest.fn();
8
+ const dispatch = vi.fn();
9
9
  getQuerystring()(dispatch, getState);
10
10
  expect(dispatch).toHaveBeenCalledWith({
11
11
  type: GET_QUERYSTRING,
@@ -21,7 +21,7 @@ describe('Querystring action', () => {
21
21
  data: { '@id': 'http://localhost:3000/some/content' },
22
22
  },
23
23
  });
24
- const dispatch = jest.fn();
24
+ const dispatch = vi.fn();
25
25
  getQuerystring()(dispatch, getState);
26
26
  expect(dispatch).toHaveBeenCalledWith({
27
27
  type: GET_QUERYSTRING,
@@ -10,7 +10,7 @@ describe('Types action', () => {
10
10
  },
11
11
  });
12
12
  const url = '/blog';
13
- const dispatch = jest.fn();
13
+ const dispatch = vi.fn();
14
14
 
15
15
  getTypes(url)(dispatch, getState);
16
16
 
@@ -8,7 +8,11 @@ import Actions from './Actions';
8
8
 
9
9
  const mockStore = configureStore();
10
10
 
11
- jest.mock('@plone/volto/components/manage/Contents');
11
+ vi.mock('@plone/volto/components/manage/Contents', async () => {
12
+ return await import(
13
+ '@plone/volto/components/manage/Contents/__mocks__/index.vitest.tsx'
14
+ );
15
+ });
12
16
 
13
17
  describe('Actions', () => {
14
18
  it('renders an actions component', () => {
@@ -359,27 +359,29 @@ class Add extends Component {
359
359
  }
360
360
  schema={this.props.schema}
361
361
  type={this.props.type}
362
- formData={{
363
- ...(blocksFieldname && {
364
- [blocksFieldname]:
365
- initialBlocks ||
366
- this.props.schema.properties[blocksFieldname]?.default,
367
- }),
368
- ...(blocksLayoutFieldname && {
369
- [blocksLayoutFieldname]: {
370
- items:
371
- initialBlocksLayout ||
372
- this.props.schema.properties[blocksLayoutFieldname]?.default
373
- ?.items,
362
+ formData={
363
+ this.props.location?.state?.initialFormData || {
364
+ ...(blocksFieldname && {
365
+ [blocksFieldname]:
366
+ initialBlocks ||
367
+ this.props.schema.properties[blocksFieldname]?.default,
368
+ }),
369
+ ...(blocksLayoutFieldname && {
370
+ [blocksLayoutFieldname]: {
371
+ items:
372
+ initialBlocksLayout ||
373
+ this.props.schema.properties[blocksLayoutFieldname]
374
+ ?.default?.items,
375
+ },
376
+ }),
377
+ // Copy the Language Independent Fields values from the to-be translated content
378
+ // into the default values of the translated content Add form.
379
+ ...lifData(),
380
+ parent: {
381
+ '@id': this.props.content?.['@id'] || '',
374
382
  },
375
- }),
376
- // Copy the Language Independent Fields values from the to-be translated content
377
- // into the default values of the translated content Add form.
378
- ...lifData(),
379
- parent: {
380
- '@id': this.props.content?.['@id'] || '',
381
- },
382
- }}
383
+ }
384
+ }
383
385
  requestError={this.state.error}
384
386
  onSubmit={this.onSubmit}
385
387
  hideActions
@@ -3,7 +3,6 @@ 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 config from '@plone/volto/registry';
6
-
7
6
  import Add from './Add';
8
7
 
9
8
  const mockStore = configureStore();
@@ -16,9 +15,13 @@ beforeAll(() => {
16
15
  config.settings.loadables = {};
17
16
  });
18
17
 
19
- jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
18
+ vi.mock('../Toolbar/Toolbar', () => ({
19
+ default: vi.fn(() => <div id="Portal" />),
20
+ }));
20
21
 
21
- jest.mock('../Form/Form', () => jest.fn(() => <div className="Form" />));
22
+ vi.mock('../Form/Form', () => ({
23
+ default: vi.fn(() => <div className="Form" />),
24
+ }));
22
25
 
23
26
  describe('Add', () => {
24
27
  it('renders an empty add component', () => {
@@ -9,9 +9,13 @@ import Aliases from './Aliases';
9
9
  const middlewares = [thunk];
10
10
  const mockStore = configureMockStore(middlewares);
11
11
 
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
- jest.mock('../Toolbar/More', () => jest.fn(() => <div className="More" />));
16
+ vi.mock('../Toolbar/More', () => ({
17
+ default: vi.fn(() => <div className="More" />),
18
+ }));
15
19
 
16
20
  describe('Aliases', () => {
17
21
  it('renders aliases object control', () => {
@@ -27,11 +31,7 @@ describe('Aliases', () => {
27
31
  loading: false,
28
32
  error: null,
29
33
  },
30
- get: {
31
- loading: false,
32
- loaded: true,
33
- error: null,
34
- },
34
+ get: { __esModule: true, loading: false, loaded: true, error: null },
35
35
  items: [],
36
36
  },
37
37
  content: {
@@ -359,6 +359,7 @@ const BlocksForm = (props) => {
359
359
  editable,
360
360
  showBlockChooser: selectedBlock === childId,
361
361
  detached: isContainer,
362
+ isContainer,
362
363
  // Properties to pass to the BlocksForm to match the View ones
363
364
  content: properties,
364
365
  history,
@@ -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
- jest.mock('@plone/volto/helpers/Loadable/Loadable');
12
- beforeAll(
13
- async () =>
14
- await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
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
- let mockSerial = 0;
16
+ beforeAll(async () => {
17
+ const { __setLoadables } = await import(
18
+ '@plone/volto/helpers/Loadable/Loadable'
19
+ );
20
+ await __setLoadables();
21
+ });
18
22
 
19
- jest.mock('uuid', () => {
23
+ let mockSerial = 0;
24
+ vi.mock('uuid', () => {
20
25
  return {
21
- v4: jest.fn().mockImplementation(() => `id-${mockSerial++}`),
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
- <BlocksForm {...data} />
74
- <div id="sidebar-order"></div>
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 = jest.fn(() => {});
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
- <BlocksForm {...data} />
130
- <div id="sidebar-order"></div>
157
+ <div>
158
+ <BlocksForm {...data} />
159
+ <div id="sidebar-order"></div>
160
+ </div>
131
161
  </Provider>,
132
162
  );
133
- expect(onChangeFormData).toBeCalledWith({
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
- expect(onChangeFormData).toBeCalledWith({
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
- jest.mock('@plone/volto/components/manage/Form');
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 { block, children, content, data = {}, isContainer } = props;
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
- isContainer && content.blocks ? content : {},
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
- test('renders a view description component', () => {
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
- 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', 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
- test('renders a view html component', () => {
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
- jest.mock('@plone/volto/components/manage/Form');
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
- test('renders an Image Block Sidebar component', () => {
16
+ it('renders an Image Block Sidebar component', () => {
13
17
  const store = mockStore({
14
18
  content: {
15
19
  create: {},