@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
@@ -3,36 +3,40 @@ import renderer from 'react-test-renderer';
3
3
  import config from '@plone/volto/registry';
4
4
  import Html from './Html';
5
5
 
6
- jest.mock('../Helmet/Helmet', () => ({
7
- rewind: () => ({
8
- base: {
9
- toComponent: () => '',
10
- },
11
- title: {
12
- toComponent: () => '',
13
- },
14
- meta: {
15
- toComponent: () => '',
16
- },
17
- link: {
18
- toComponent: () => '',
19
- },
20
- script: {
21
- toComponent: () => '',
22
- },
23
- style: {
24
- toComponent: () => '',
25
- },
26
- htmlAttributes: {
27
- toComponent: () => ({
28
- lang: 'en',
29
- }),
30
- },
31
- }),
6
+ vi.mock('../Helmet/Helmet', () => ({
7
+ default: {
8
+ rewind: () => ({
9
+ base: {
10
+ toComponent: () => '',
11
+ },
12
+ title: {
13
+ toComponent: () => '',
14
+ },
15
+ meta: {
16
+ toComponent: () => '',
17
+ },
18
+ link: {
19
+ toComponent: () => '',
20
+ },
21
+ script: {
22
+ toComponent: () => '',
23
+ },
24
+ style: {
25
+ toComponent: () => '',
26
+ },
27
+ htmlAttributes: {
28
+ toComponent: () => ({
29
+ lang: 'en',
30
+ }),
31
+ },
32
+ }),
33
+ },
32
34
  }));
33
35
 
34
- jest.mock('../BodyClass/BodyClass', () => ({
35
- rewind: () => ['class1', 'class2'],
36
+ vi.mock('../BodyClass/BodyClass', () => ({
37
+ default: {
38
+ rewind: () => ['class1', 'class2'],
39
+ },
36
40
  }));
37
41
 
38
42
  config.settings = {};
@@ -1,4 +1,19 @@
1
- import React from 'react';
1
+ /* TODO: When the Volto Team removes Jest configuration support from Volto core, update this file with the Vitest version of the mock.
2
+ Then, in the tests, we need to replace:
3
+
4
+ vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
5
+ return await import(
6
+ '@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
7
+ );
8
+ });
9
+
10
+ with the following:
11
+
12
+ vi.mock('@plone/volto/helpers/Loadable/Loadable');
13
+
14
+ Finally, remove this comment.
15
+ */
16
+
2
17
  import config from '@plone/volto/registry';
3
18
  const loadables = config.settings.loadables;
4
19
 
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import config from '@plone/volto/registry';
3
+ const loadables = config.settings.loadables;
4
+
5
+ let mockAllLoadables = Object.create(null);
6
+
7
+ export const __setLoadables = async () => {
8
+ if (Object.keys(mockAllLoadables).length > 0) return;
9
+ const resolved = await Promise.all(
10
+ Object.keys(loadables).map(async (n) => {
11
+ const lib = await Promise.resolve(loadables[n].load());
12
+ return [n, { current: lib }];
13
+ }),
14
+ );
15
+ resolved.forEach(([name, { current }]) => {
16
+ mockAllLoadables[name] = current;
17
+ });
18
+ };
19
+
20
+ // TODO: filter mockAllLoadables
21
+ export const injectLazyLibs = vi.fn().mockImplementation(function ([
22
+ libraries,
23
+ ]) {
24
+ return vi.fn((WrappedComponent) =>
25
+ vi.fn((props) => {
26
+ return <WrappedComponent {...props} {...mockAllLoadables} />;
27
+ }),
28
+ );
29
+ });
30
+
31
+ export const preloadLazyLibs = vi.fn().mockImplementation(function ([
32
+ libraries,
33
+ ]) {
34
+ return vi.fn((WrappedComponent) =>
35
+ vi.fn((props) => {
36
+ return <WrappedComponent {...props} />;
37
+ }),
38
+ );
39
+ });
@@ -282,4 +282,51 @@ describe('api middleware helpers', () => {
282
282
  '/de/mypage?expand=navigation&expand.navigation.coolness=1&expand.navigation.depth=3&someotherquery=1&someotherquery=2',
283
283
  );
284
284
  });
285
+
286
+ it('addExpandersToPath - inherit expander merged using querystring as a function', () => {
287
+ config.settings.apiExpanders = [
288
+ {
289
+ match: '/',
290
+ GET_CONTENT: ['navigation'],
291
+ querystring: {
292
+ 'expand.navigation.depth': 3,
293
+ 'expand.navigation.coolness': 1,
294
+ },
295
+ },
296
+ {
297
+ match: '/',
298
+ GET_CONTENT: ['inherit'],
299
+ querystring: {
300
+ 'expand.inherit.behaviors':
301
+ 'voltolighttheme.header,voltolighttheme.theme,voltolighttheme.footer',
302
+ },
303
+ },
304
+ {
305
+ match: '/',
306
+ GET_CONTENT: ['inherit'],
307
+ querystring: (config, querystring) => {
308
+ if (querystring['expand.inherit.behaviors']) {
309
+ return {
310
+ 'expand.inherit.behaviors': querystring[
311
+ 'expand.inherit.behaviors'
312
+ ].concat(',', 'plonegovbr.socialmedia.settings'),
313
+ };
314
+ } else {
315
+ return {
316
+ 'expand.inherit.behaviors': 'plonegovbr.socialmedia.settings',
317
+ };
318
+ }
319
+ },
320
+ },
321
+ ];
322
+
323
+ const result = addExpandersToPath(
324
+ '/de/mypage?someotherquery=1&someotherquery=2',
325
+ GET_CONTENT,
326
+ );
327
+
328
+ expect(result).toEqual(
329
+ '/de/mypage?expand=navigation,inherit&expand.inherit.behaviors=voltolighttheme.header,voltolighttheme.theme,voltolighttheme.footer,plonegovbr.socialmedia.settings&expand.navigation.coolness=1&expand.navigation.depth=3&someotherquery=1&someotherquery=2',
330
+ );
331
+ });
285
332
  });
@@ -75,7 +75,7 @@ export function addExpandersToPath(path, type, isAnonymous) {
75
75
  // The querystring accepts being a function to be able to take other
76
76
  // config parameters
77
77
  if (typeof querystring === 'function') {
78
- querystring = querystring(config);
78
+ querystring = querystring(config, acc);
79
79
  }
80
80
  return { ...acc, ...querystring };
81
81
  }, {});
@@ -6,76 +6,81 @@ import {
6
6
  import * as Url from '../helpers/Url/Url';
7
7
 
8
8
  const tick = async () => new Promise((resolve) => setTimeout(resolve, 0));
9
+ Object.defineProperty(Url, 'isCmsUi', {
10
+ value: vi.fn((path) => locationMap[path]),
11
+ writable: true,
12
+ });
13
+ let locationMap;
9
14
 
10
15
  describe('storeProtectLoadUtils', () => {
11
16
  describe('protectLoadStart middleware', () => {
12
17
  test('idle', () => {
13
- const dispatch = jest.fn();
14
- const getState = jest.fn(() => ({
18
+ const dispatch = vi.fn();
19
+ const getState = vi.fn(() => ({
15
20
  router: {
16
21
  location: {
17
22
  pathname: '/PATH',
18
23
  },
19
24
  },
20
25
  }));
21
- const next = jest.fn(() => 'NEXT');
26
+ const next = vi.fn(() => 'NEXT');
22
27
  const action = { type: 'ANY' };
23
28
  const result = protectLoadStart({ dispatch, getState })(next)(action);
24
- expect(dispatch).toBeCalledTimes(0);
25
- expect(next).toBeCalledWith(action);
29
+ expect(dispatch).toHaveBeenCalledTimes(0);
30
+ expect(next).toHaveBeenCalledWith(action);
26
31
  expect(result).toBe('NEXT');
27
32
  });
28
33
 
29
34
  const testLocationChange =
30
35
  ({ locationMap, resetBeforeFetch }) =>
31
36
  () => {
32
- const dispatch = jest.fn();
33
- const getState = jest.fn(() => ({
37
+ const dispatch = vi.fn();
38
+ const getState = vi.fn(() => ({
34
39
  router: {
35
40
  location: {
36
41
  pathname: '/PATH',
37
42
  },
38
43
  },
39
44
  }));
40
- const next = jest.fn(() => 'NEXT');
45
+ const next = vi.fn(() => 'NEXT');
41
46
  const action = {
42
47
  type: '@@router/LOCATION_CHANGE',
43
48
  payload: { location: { pathname: '/NEW-PATH' } },
44
49
  };
45
- Url.isCmsUi = jest.fn((path) => locationMap[path]);
50
+ Url.isCmsUi = vi.fn((path) => locationMap[path]);
46
51
  const result = protectLoadStart({ dispatch, getState })(next)(action);
47
- expect(dispatch).toBeCalledWith({
52
+ expect(dispatch).toHaveBeenCalledWith({
48
53
  type: '@@loadProtector/START',
49
54
  location: { pathname: '/NEW-PATH' },
50
55
  resetBeforeFetch,
51
56
  });
52
- expect(next).toBeCalledWith(action);
57
+ expect(next).toHaveBeenCalledWith(action);
53
58
  expect(result).toBe('NEXT');
54
59
  };
55
60
 
56
61
  const testLocationSkipped =
57
62
  ({ locationMap }) =>
58
63
  () => {
59
- const dispatch = jest.fn();
60
- const getState = jest.fn(() => ({
64
+ const dispatch = vi.fn();
65
+ const getState = vi.fn(() => ({
61
66
  router: {
62
67
  location: {
63
68
  pathname: '/PATH',
64
69
  },
65
70
  },
66
71
  }));
67
- const next = jest.fn(() => 'NEXT');
72
+ const next = vi.fn(() => 'NEXT');
68
73
  const action = {
69
74
  type: '@@router/LOCATION_CHANGE',
70
75
  payload: { location: { pathname: '/NEW-PATH' } },
71
76
  };
72
- Url.isCmsUi = jest.fn((path) => locationMap[path]);
77
+ Url.isCmsUi = vi.fn((path) => locationMap[path]);
73
78
  const result = protectLoadStart({ dispatch, getState })(next)(action);
74
- expect(dispatch).toBeCalledWith({
79
+ expect(dispatch).toHaveBeenCalledWith({
75
80
  type: '@@loadProtector/SKIPPED',
76
81
  location: { pathname: '/NEW-PATH' },
77
82
  });
78
- expect(next).toBeCalledWith(action);
83
+ expect(next).toHaveBeenCalledWith(action);
79
84
  expect(result).toBe('NEXT');
80
85
  };
81
86
 
@@ -109,182 +114,182 @@ describe('storeProtectLoadUtils', () => {
109
114
  });
110
115
 
111
116
  test('skips functional actions', () => {
112
- const dispatch = jest.fn();
113
- const getState = jest.fn(() => ({
117
+ const dispatch = vi.fn();
118
+ const getState = vi.fn(() => ({
114
119
  router: {
115
120
  location: {
116
121
  pathname: '/PATH',
117
122
  },
118
123
  },
119
124
  }));
120
- const next = jest.fn(() => 'NEXT');
125
+ const next = vi.fn(() => 'NEXT');
121
126
  const action = () => {};
122
127
  const result = protectLoadStart({ dispatch, getState })(next)(action);
123
- expect(dispatch).toBeCalledTimes(0);
124
- expect(next).toBeCalledWith(action);
128
+ expect(dispatch).toHaveBeenCalledTimes(0);
129
+ expect(next).toHaveBeenCalledWith(action);
125
130
  expect(result).toBe('NEXT');
126
131
  });
127
132
  });
128
133
 
129
134
  describe('protectLoadEnd middleware', () => {
130
135
  test('idle', async () => {
131
- const dispatch = jest.fn();
132
- const getState = jest.fn(() => ({
136
+ const dispatch = vi.fn();
137
+ const getState = vi.fn(() => ({
133
138
  loadProtector: {
134
139
  isCounting: false,
135
140
  },
136
141
  }));
137
- const next = jest.fn(() => 'NEXT');
142
+ const next = vi.fn(() => 'NEXT');
138
143
  const action = { type: 'ANY' };
139
144
  const result = protectLoadEnd({ dispatch, getState })(next)(action);
140
- expect(dispatch).toBeCalledTimes(0);
141
- expect(next).toBeCalledWith(action);
145
+ expect(dispatch).toHaveBeenCalledTimes(0);
146
+ expect(next).toHaveBeenCalledWith(action);
142
147
  expect(result).toBe('NEXT');
143
148
  await tick();
144
- expect(dispatch).toBeCalledTimes(0);
149
+ expect(dispatch).toHaveBeenCalledTimes(0);
145
150
  });
146
151
 
147
152
  test('not dispatching', async () => {
148
- const dispatch = jest.fn();
149
- const getState = jest.fn(() => ({
153
+ const dispatch = vi.fn();
154
+ const getState = vi.fn(() => ({
150
155
  loadProtector: {
151
156
  isCounting: true,
152
157
  },
153
158
  }));
154
- const next = jest.fn(() => 'NEXT');
159
+ const next = vi.fn(() => 'NEXT');
155
160
  const action = { type: 'ANY' };
156
161
  const result = protectLoadEnd({ dispatch, getState })(next)(action);
157
- expect(dispatch).toBeCalledTimes(0);
158
- expect(next).toBeCalledWith(action);
162
+ expect(dispatch).toHaveBeenCalledTimes(0);
163
+ expect(next).toHaveBeenCalledWith(action);
159
164
  expect(result).toBe('NEXT');
160
165
  await tick();
161
- expect(dispatch).toBeCalledTimes(0);
166
+ expect(dispatch).toHaveBeenCalledTimes(0);
162
167
  });
163
168
 
164
169
  test('skip functional actions', async () => {
165
- const dispatch = jest.fn();
166
- const getState = jest.fn(() => ({
170
+ const dispatch = vi.fn();
171
+ const getState = vi.fn(() => ({
167
172
  loadProtector: {
168
173
  isCounting: true,
169
174
  },
170
175
  }));
171
- const next = jest.fn(() => 'NEXT');
176
+ const next = vi.fn(() => 'NEXT');
172
177
  const action = () => {};
173
178
  const result = protectLoadEnd({ dispatch, getState })(next)(action);
174
- expect(dispatch).toBeCalledTimes(0);
175
- expect(next).toBeCalledWith(action);
179
+ expect(dispatch).toHaveBeenCalledTimes(0);
180
+ expect(next).toHaveBeenCalledWith(action);
176
181
  expect(result).toBe('NEXT');
177
182
  await tick();
178
- expect(dispatch).toBeCalledTimes(0);
183
+ expect(dispatch).toHaveBeenCalledTimes(0);
179
184
  });
180
185
 
181
186
  test('resetting', async () => {
182
- const dispatch = jest.fn();
183
- const getState = jest.fn(() => ({
187
+ const dispatch = vi.fn();
188
+ const getState = vi.fn(() => ({
184
189
  loadProtector: {
185
190
  resetBeforeFetch: true,
186
191
  },
187
192
  }));
188
- const next = jest.fn(() => 'NEXT');
193
+ const next = vi.fn(() => 'NEXT');
189
194
  const action = { type: 'GET_CONTENT_PENDING' };
190
195
  const result = protectLoadEnd({ dispatch, getState })(next)(action);
191
- expect(dispatch).toBeCalledWith({ type: 'RESET_CONTENT' });
192
- expect(next).toBeCalledWith(action);
196
+ expect(dispatch).toHaveBeenCalledWith({ type: 'RESET_CONTENT' });
197
+ expect(next).toHaveBeenCalledWith(action);
193
198
  expect(result).toBe('NEXT');
194
199
  await tick();
195
- expect(dispatch).toBeCalledTimes(1);
200
+ expect(dispatch).toHaveBeenCalledTimes(1);
196
201
  });
197
202
 
198
203
  test('not resetting on content-content transition ', async () => {
199
- const dispatch = jest.fn();
200
- const getState = jest.fn(() => ({
204
+ const dispatch = vi.fn();
205
+ const getState = vi.fn(() => ({
201
206
  loadProtector: {
202
207
  isCounting: true,
203
208
  resetBeforeFetch: false,
204
209
  },
205
210
  }));
206
- const next = jest.fn(() => 'NEXT');
211
+ const next = vi.fn(() => 'NEXT');
207
212
  const action = { type: 'GET_CONTENT_PENDING' };
208
213
  const result = protectLoadEnd({ dispatch, getState })(next)(action);
209
- expect(dispatch).toBeCalledTimes(0);
210
- expect(next).toBeCalledWith(action);
214
+ expect(dispatch).toHaveBeenCalledTimes(0);
215
+ expect(next).toHaveBeenCalledWith(action);
211
216
  expect(result).toBe('NEXT');
212
217
  await tick();
213
- expect(dispatch).toBeCalledTimes(0);
218
+ expect(dispatch).toHaveBeenCalledTimes(0);
214
219
  });
215
220
 
216
221
  test('counting down when success', async () => {
217
- const dispatch = jest.fn();
218
- const getState = jest.fn(() => ({
222
+ const dispatch = vi.fn();
223
+ const getState = vi.fn(() => ({
219
224
  loadProtector: {
220
225
  isCounting: true,
221
226
  requestCount: 2,
222
227
  },
223
228
  }));
224
- const next = jest.fn(() => 'NEXT');
229
+ const next = vi.fn(() => 'NEXT');
225
230
  const action = { type: 'ANY_SUCCESS' };
226
231
  const result = protectLoadEnd({ dispatch, getState })(next)(action);
227
- expect(dispatch).toBeCalledTimes(0);
228
- expect(next).toBeCalledWith(action);
232
+ expect(dispatch).toHaveBeenCalledTimes(0);
233
+ expect(next).toHaveBeenCalledWith(action);
229
234
  expect(result).toBe('NEXT');
230
235
  await tick();
231
- expect(dispatch).toBeCalledTimes(0);
236
+ expect(dispatch).toHaveBeenCalledTimes(0);
232
237
  });
233
238
 
234
239
  test('counting down when failure', async () => {
235
- const dispatch = jest.fn();
236
- const getState = jest.fn(() => ({
240
+ const dispatch = vi.fn();
241
+ const getState = vi.fn(() => ({
237
242
  loadProtector: {
238
243
  isCounting: true,
239
244
  requestCount: 2,
240
245
  },
241
246
  }));
242
- const next = jest.fn(() => 'NEXT');
247
+ const next = vi.fn(() => 'NEXT');
243
248
  const action = { type: 'ANY_FAIL' };
244
249
  const result = protectLoadEnd({ dispatch, getState })(next)(action);
245
- expect(dispatch).toBeCalledTimes(0);
246
- expect(next).toBeCalledWith(action);
250
+ expect(dispatch).toHaveBeenCalledTimes(0);
251
+ expect(next).toHaveBeenCalledWith(action);
247
252
  expect(result).toBe('NEXT');
248
253
  await tick();
249
- expect(dispatch).toBeCalledTimes(0);
254
+ expect(dispatch).toHaveBeenCalledTimes(0);
250
255
  });
251
256
 
252
257
  test('ending protect when success', async () => {
253
- const dispatch = jest.fn();
254
- const getState = jest.fn(() => ({
258
+ const dispatch = vi.fn();
259
+ const getState = vi.fn(() => ({
255
260
  loadProtector: {
256
261
  isCounting: true,
257
262
  requestCount: 1,
258
263
  },
259
264
  }));
260
- const next = jest.fn(() => 'NEXT');
265
+ const next = vi.fn(() => 'NEXT');
261
266
  const action = { type: 'ANY_SUCCESS' };
262
267
  const result = protectLoadEnd({ dispatch, getState })(next)(action);
263
- expect(dispatch).toBeCalledTimes(0);
264
- expect(next).toBeCalledWith(action);
268
+ expect(dispatch).toHaveBeenCalledTimes(0);
269
+ expect(next).toHaveBeenCalledWith(action);
265
270
  expect(result).toBe('NEXT');
266
271
  await tick();
267
- expect(dispatch).toBeCalledTimes(1);
268
- expect(dispatch).toBeCalledWith({ type: '@@loadProtector/END' });
272
+ expect(dispatch).toHaveBeenCalledTimes(1);
273
+ expect(dispatch).toHaveBeenCalledWith({ type: '@@loadProtector/END' });
269
274
  });
270
275
 
271
276
  test('ending protect when failure', async () => {
272
- const dispatch = jest.fn();
273
- const getState = jest.fn(() => ({
277
+ const dispatch = vi.fn();
278
+ const getState = vi.fn(() => ({
274
279
  loadProtector: {
275
280
  isCounting: true,
276
281
  requestCount: 1,
277
282
  },
278
283
  }));
279
- const next = jest.fn(() => 'NEXT');
284
+ const next = vi.fn(() => 'NEXT');
280
285
  const action = { type: 'ANY_FAIL' };
281
286
  const result = protectLoadEnd({ dispatch, getState })(next)(action);
282
- expect(dispatch).toBeCalledTimes(0);
283
- expect(next).toBeCalledWith(action);
287
+ expect(dispatch).toHaveBeenCalledTimes(0);
288
+ expect(next).toHaveBeenCalledWith(action);
284
289
  expect(result).toBe('NEXT');
285
290
  await tick();
286
- expect(dispatch).toBeCalledTimes(1);
287
- expect(dispatch).toBeCalledWith({ type: '@@loadProtector/END' });
291
+ expect(dispatch).toHaveBeenCalledTimes(1);
292
+ expect(dispatch).toHaveBeenCalledWith({ type: '@@loadProtector/END' });
288
293
  });
289
294
  });
290
295
 
@@ -302,6 +307,7 @@ describe('storeProtectLoadUtils', () => {
302
307
  isCounting: true,
303
308
  });
304
309
  });
310
+
305
311
  test('PROTECT_END', () => {
306
312
  const state = {
307
313
  foo: 'BAR',
@@ -318,6 +324,7 @@ describe('storeProtectLoadUtils', () => {
318
324
  resetBeforeFetch: false,
319
325
  });
320
326
  });
327
+
321
328
  test('PROTECT_SKIPPED', () => {
322
329
  const state = {
323
330
  foo: 'BAR',
@@ -339,6 +346,7 @@ describe('storeProtectLoadUtils', () => {
339
346
  location: { pathname: '/NEW-PATH' },
340
347
  });
341
348
  });
349
+
342
350
  test('GET_CONTENT_SUCCESS pass when not counting', () => {
343
351
  const state = {
344
352
  foo: 'BAR',
@@ -353,6 +361,7 @@ describe('storeProtectLoadUtils', () => {
353
361
  isCounting: false,
354
362
  });
355
363
  });
364
+
356
365
  test('GET_CONTENT_FAIL pass when not counting', () => {
357
366
  const state = {
358
367
  foo: 'BAR',
@@ -367,6 +376,7 @@ describe('storeProtectLoadUtils', () => {
367
376
  isCounting: false,
368
377
  });
369
378
  });
379
+
370
380
  test('GET_CONTENT_SUCCESS when counting', () => {
371
381
  const state = {
372
382
  foo: 'BAR',
@@ -386,6 +396,7 @@ describe('storeProtectLoadUtils', () => {
386
396
  location: { pathname: '/NEW-PATH' },
387
397
  });
388
398
  });
399
+
389
400
  test('GET_CONTENT_FAIL when counting', () => {
390
401
  const state = {
391
402
  foo: 'BAR',
@@ -405,6 +416,7 @@ describe('storeProtectLoadUtils', () => {
405
416
  location: { pathname: '/NEW-PATH' },
406
417
  });
407
418
  });
419
+
408
420
  test('RESET_CONTENT will remove the reset condition', () => {
409
421
  const state = {
410
422
  foo: 'BAR',
@@ -0,0 +1,46 @@
1
+ import '@testing-library/jest-dom';
2
+ import { expect, describe, it, vi } from 'vitest';
3
+
4
+ global.describe = describe;
5
+ global.it = it;
6
+ global.expect = expect;
7
+ global.vi = vi;
8
+
9
+ global.__CLIENT__ = true;
10
+ global.__DEVELOPMENT__ = false;
11
+ global.__SERVER__ = false;
12
+ global.__TEST__ = true;
13
+
14
+ window.matchMedia =
15
+ window.matchMedia ||
16
+ function (query) {
17
+ return {
18
+ matches: query === '(min-width: 1024px)',
19
+ addListener: function () {},
20
+ removeListener: function () {},
21
+ };
22
+ };
23
+
24
+ vi.stubGlobal(
25
+ 'fetch',
26
+ vi.fn(() =>
27
+ Promise.resolve({
28
+ json: () => Promise.resolve({}),
29
+ text: () => Promise.resolve(''),
30
+ }),
31
+ ),
32
+ );
33
+
34
+ vi.stubGlobal('localStorage', {
35
+ getItem: vi.fn(),
36
+ setItem: vi.fn(),
37
+ removeItem: vi.fn(),
38
+ clear: vi.fn(),
39
+ });
40
+
41
+ vi.stubGlobal('sessionStorage', {
42
+ getItem: vi.fn(),
43
+ setItem: vi.fn(),
44
+ removeItem: vi.fn(),
45
+ clear: vi.fn(),
46
+ });
@@ -10,11 +10,22 @@
10
10
  "jsx": "react-jsx",
11
11
  "preserveSymlinks": true,
12
12
  "downlevelIteration": true,
13
+ "types": ["vitest/globals", "jest"],
13
14
  "paths": {
14
15
  "@plone/volto/*": ["./src/*"],
15
16
  "react": ["./node_modules/@types/react"],
16
17
  "react-dom": ["./node_modules/@types/react-dom"]
17
18
  }
18
19
  },
19
- "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.tsx"]
20
+ "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.tsx"],
21
+ "exclude": [
22
+ "node_modules",
23
+ "build",
24
+ "coverage",
25
+ "dist",
26
+ "types",
27
+ "**/*.test.js",
28
+ "**/*.test.tsx",
29
+ "**/*.test.ts"
30
+ ]
20
31
  }
package/tsconfig.json CHANGED
@@ -2,6 +2,7 @@
2
2
  "compilerOptions": {
3
3
  "target": "ESNext",
4
4
  "lib": ["DOM", "DOM.Iterable", "ESNext"],
5
+ "types": ["vitest/globals", "jest"],
5
6
  "module": "commonjs",
6
7
  "allowJs": true,
7
8
  "skipLibCheck": true,
@@ -21,7 +22,7 @@
21
22
  "@root/*": ["./src/*"]
22
23
  }
23
24
  },
24
- "include": ["src", "packages"],
25
+ "include": ["src", "packages", "types", "vitest.config.ts"],
25
26
  "exclude": [
26
27
  "node_modules",
27
28
  "build",