@pranaysahith/decap-cms-core 3.9.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 (299) hide show
  1. package/README.md +9 -0
  2. package/dist/@pranaysahith/decap-cms-core.js +52 -0
  3. package/dist/@pranaysahith/decap-cms-core.js.LICENSE.txt +141 -0
  4. package/dist/@pranaysahith/decap-cms-core.js.map +1 -0
  5. package/dist/decap-cms-core.js +47 -0
  6. package/dist/decap-cms-core.js.LICENSE.txt +116 -0
  7. package/dist/decap-cms-core.js.map +1 -0
  8. package/dist/esm/actions/auth.js +97 -0
  9. package/dist/esm/actions/collections.js +15 -0
  10. package/dist/esm/actions/config.js +493 -0
  11. package/dist/esm/actions/deploys.js +79 -0
  12. package/dist/esm/actions/editorialWorkflow.js +480 -0
  13. package/dist/esm/actions/entries.js +865 -0
  14. package/dist/esm/actions/media.js +147 -0
  15. package/dist/esm/actions/mediaLibrary.js +552 -0
  16. package/dist/esm/actions/notifications.js +21 -0
  17. package/dist/esm/actions/search.js +149 -0
  18. package/dist/esm/actions/status.js +74 -0
  19. package/dist/esm/actions/waitUntil.js +32 -0
  20. package/dist/esm/backend.js +1082 -0
  21. package/dist/esm/bootstrap.js +101 -0
  22. package/dist/esm/components/App/App.js +289 -0
  23. package/dist/esm/components/App/Header.js +172 -0
  24. package/dist/esm/components/App/NotFoundPage.js +19 -0
  25. package/dist/esm/components/Collection/Collection.js +198 -0
  26. package/dist/esm/components/Collection/CollectionControls.js +46 -0
  27. package/dist/esm/components/Collection/CollectionSearch.js +222 -0
  28. package/dist/esm/components/Collection/CollectionTop.js +68 -0
  29. package/dist/esm/components/Collection/ControlButton.js +17 -0
  30. package/dist/esm/components/Collection/Entries/Entries.js +73 -0
  31. package/dist/esm/components/Collection/Entries/EntriesCollection.js +241 -0
  32. package/dist/esm/components/Collection/Entries/EntriesSearch.js +113 -0
  33. package/dist/esm/components/Collection/Entries/EntryCard.js +177 -0
  34. package/dist/esm/components/Collection/Entries/EntryListing.js +143 -0
  35. package/dist/esm/components/Collection/FilterControl.js +33 -0
  36. package/dist/esm/components/Collection/FolderRenameControl.js +403 -0
  37. package/dist/esm/components/Collection/GroupControl.js +33 -0
  38. package/dist/esm/components/Collection/NestedCollection.js +308 -0
  39. package/dist/esm/components/Collection/Sidebar.js +91 -0
  40. package/dist/esm/components/Collection/SortControl.js +59 -0
  41. package/dist/esm/components/Collection/ViewStyleControl.js +38 -0
  42. package/dist/esm/components/Editor/Editor.js +466 -0
  43. package/dist/esm/components/Editor/EditorControlPane/EditorControl.js +395 -0
  44. package/dist/esm/components/Editor/EditorControlPane/EditorControlPane.js +254 -0
  45. package/dist/esm/components/Editor/EditorControlPane/Widget.js +374 -0
  46. package/dist/esm/components/Editor/EditorInterface.js +386 -0
  47. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreview.js +47 -0
  48. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewContent.js +66 -0
  49. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewPane.js +288 -0
  50. package/dist/esm/components/Editor/EditorPreviewPane/PreviewHOC.js +27 -0
  51. package/dist/esm/components/Editor/EditorToolbar.js +536 -0
  52. package/dist/esm/components/Editor/EntryPathEditor.js +272 -0
  53. package/dist/esm/components/Editor/withWorkflow.js +56 -0
  54. package/dist/esm/components/EditorWidgets/Unknown/UnknownControl.js +18 -0
  55. package/dist/esm/components/EditorWidgets/Unknown/UnknownPreview.js +20 -0
  56. package/dist/esm/components/EditorWidgets/index.js +4 -0
  57. package/dist/esm/components/MediaLibrary/EmptyMessage.js +22 -0
  58. package/dist/esm/components/MediaLibrary/MediaLibrary.js +446 -0
  59. package/dist/esm/components/MediaLibrary/MediaLibraryButtons.js +93 -0
  60. package/dist/esm/components/MediaLibrary/MediaLibraryCard.js +99 -0
  61. package/dist/esm/components/MediaLibrary/MediaLibraryCardGrid.js +198 -0
  62. package/dist/esm/components/MediaLibrary/MediaLibraryHeader.js +32 -0
  63. package/dist/esm/components/MediaLibrary/MediaLibraryModal.js +156 -0
  64. package/dist/esm/components/MediaLibrary/MediaLibrarySearch.js +51 -0
  65. package/dist/esm/components/MediaLibrary/MediaLibraryTop.js +123 -0
  66. package/dist/esm/components/UI/DragDrop.js +67 -0
  67. package/dist/esm/components/UI/ErrorBoundary.js +173 -0
  68. package/dist/esm/components/UI/FileUploadButton.js +27 -0
  69. package/dist/esm/components/UI/Modal.js +104 -0
  70. package/dist/esm/components/UI/Notifications.js +62 -0
  71. package/dist/esm/components/UI/SettingsDropdown.js +107 -0
  72. package/dist/esm/components/UI/index.js +6 -0
  73. package/dist/esm/components/Workflow/Workflow.js +133 -0
  74. package/dist/esm/components/Workflow/WorkflowCard.js +128 -0
  75. package/dist/esm/components/Workflow/WorkflowList.js +204 -0
  76. package/dist/esm/constants/collectionTypes.js +2 -0
  77. package/dist/esm/constants/collectionViews.js +2 -0
  78. package/dist/esm/constants/commitProps.js +2 -0
  79. package/dist/esm/constants/configSchema.js +644 -0
  80. package/dist/esm/constants/fieldInference.js +57 -0
  81. package/dist/esm/constants/publishModes.js +18 -0
  82. package/dist/esm/constants/validationErrorTypes.js +6 -0
  83. package/dist/esm/formats/formats.js +83 -0
  84. package/dist/esm/formats/frontmatter.js +146 -0
  85. package/dist/esm/formats/helpers.js +12 -0
  86. package/dist/esm/formats/json.js +8 -0
  87. package/dist/esm/formats/toml.js +32 -0
  88. package/dist/esm/formats/yaml.js +51 -0
  89. package/dist/esm/index.js +7 -0
  90. package/dist/esm/integrations/index.js +28 -0
  91. package/dist/esm/integrations/providers/algolia/implementation.js +174 -0
  92. package/dist/esm/integrations/providers/assetStore/implementation.js +165 -0
  93. package/dist/esm/lib/consoleError.js +3 -0
  94. package/dist/esm/lib/formatters.js +191 -0
  95. package/dist/esm/lib/i18n.js +367 -0
  96. package/dist/esm/lib/phrases.js +6 -0
  97. package/dist/esm/lib/polyfill.js +8 -0
  98. package/dist/esm/lib/registry.js +329 -0
  99. package/dist/esm/lib/serializeEntryValues.js +67 -0
  100. package/dist/esm/lib/stega.js +142 -0
  101. package/dist/esm/lib/textHelper.js +9 -0
  102. package/dist/esm/lib/urlHelper.js +111 -0
  103. package/dist/esm/mediaLibrary.js +37 -0
  104. package/dist/esm/reducers/auth.js +27 -0
  105. package/dist/esm/reducers/collections.js +428 -0
  106. package/dist/esm/reducers/combinedReducer.js +8 -0
  107. package/dist/esm/reducers/config.js +29 -0
  108. package/dist/esm/reducers/cursors.js +31 -0
  109. package/dist/esm/reducers/deploys.js +45 -0
  110. package/dist/esm/reducers/editorialWorkflow.js +83 -0
  111. package/dist/esm/reducers/entries.js +568 -0
  112. package/dist/esm/reducers/entryDraft.js +212 -0
  113. package/dist/esm/reducers/globalUI.js +25 -0
  114. package/dist/esm/reducers/index.js +66 -0
  115. package/dist/esm/reducers/integrations.js +53 -0
  116. package/dist/esm/reducers/mediaLibrary.js +252 -0
  117. package/dist/esm/reducers/medias.js +68 -0
  118. package/dist/esm/reducers/notifications.js +23 -0
  119. package/dist/esm/reducers/search.js +92 -0
  120. package/dist/esm/reducers/status.js +30 -0
  121. package/dist/esm/redux/index.js +7 -0
  122. package/dist/esm/redux/middleware/waitUntilAction.js +48 -0
  123. package/dist/esm/routing/history.js +12 -0
  124. package/dist/esm/types/diacritics.d.js +0 -0
  125. package/dist/esm/types/global.d.js +1 -0
  126. package/dist/esm/types/immutable.js +7 -0
  127. package/dist/esm/types/redux.js +14 -0
  128. package/dist/esm/types/tomlify-j0.4.d.js +0 -0
  129. package/dist/esm/valueObjects/AssetProxy.js +44 -0
  130. package/dist/esm/valueObjects/EditorComponent.js +34 -0
  131. package/dist/esm/valueObjects/Entry.js +20 -0
  132. package/index.d.ts +618 -0
  133. package/package.json +106 -0
  134. package/src/__tests__/backend.spec.js +1161 -0
  135. package/src/actions/__tests__/config.spec.js +1009 -0
  136. package/src/actions/__tests__/editorialWorkflow.spec.js +216 -0
  137. package/src/actions/__tests__/entries.spec.js +596 -0
  138. package/src/actions/__tests__/media.spec.ts +171 -0
  139. package/src/actions/__tests__/mediaLibrary.spec.js +327 -0
  140. package/src/actions/__tests__/search.spec.js +209 -0
  141. package/src/actions/auth.ts +127 -0
  142. package/src/actions/collections.ts +18 -0
  143. package/src/actions/config.ts +565 -0
  144. package/src/actions/deploys.ts +104 -0
  145. package/src/actions/editorialWorkflow.ts +567 -0
  146. package/src/actions/entries.ts +1055 -0
  147. package/src/actions/media.ts +139 -0
  148. package/src/actions/mediaLibrary.ts +574 -0
  149. package/src/actions/notifications.ts +36 -0
  150. package/src/actions/search.ts +221 -0
  151. package/src/actions/status.ts +99 -0
  152. package/src/actions/waitUntil.ts +49 -0
  153. package/src/backend.ts +1400 -0
  154. package/src/bootstrap.js +104 -0
  155. package/src/components/App/App.js +286 -0
  156. package/src/components/App/Header.js +266 -0
  157. package/src/components/App/NotFoundPage.js +23 -0
  158. package/src/components/Collection/Collection.js +210 -0
  159. package/src/components/Collection/CollectionControls.js +58 -0
  160. package/src/components/Collection/CollectionSearch.js +243 -0
  161. package/src/components/Collection/CollectionTop.js +81 -0
  162. package/src/components/Collection/ControlButton.js +27 -0
  163. package/src/components/Collection/Entries/Entries.js +82 -0
  164. package/src/components/Collection/Entries/EntriesCollection.js +277 -0
  165. package/src/components/Collection/Entries/EntriesSearch.js +102 -0
  166. package/src/components/Collection/Entries/EntryCard.js +246 -0
  167. package/src/components/Collection/Entries/EntryListing.js +151 -0
  168. package/src/components/Collection/Entries/__tests__/EntriesCollection.spec.js +163 -0
  169. package/src/components/Collection/Entries/__tests__/__snapshots__/EntriesCollection.spec.js.snap +46 -0
  170. package/src/components/Collection/FilterControl.js +39 -0
  171. package/src/components/Collection/GroupControl.js +39 -0
  172. package/src/components/Collection/NestedCollection.js +330 -0
  173. package/src/components/Collection/Sidebar.js +136 -0
  174. package/src/components/Collection/SortControl.js +68 -0
  175. package/src/components/Collection/ViewStyleControl.js +50 -0
  176. package/src/components/Collection/__tests__/Collection.spec.js +75 -0
  177. package/src/components/Collection/__tests__/NestedCollection.spec.js +445 -0
  178. package/src/components/Collection/__tests__/Sidebar.spec.js +87 -0
  179. package/src/components/Collection/__tests__/__snapshots__/Collection.spec.js.snap +144 -0
  180. package/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap +550 -0
  181. package/src/components/Collection/__tests__/__snapshots__/Sidebar.spec.js.snap +312 -0
  182. package/src/components/Editor/Editor.js +497 -0
  183. package/src/components/Editor/EditorControlPane/EditorControl.js +452 -0
  184. package/src/components/Editor/EditorControlPane/EditorControlPane.js +269 -0
  185. package/src/components/Editor/EditorControlPane/Widget.js +384 -0
  186. package/src/components/Editor/EditorInterface.js +444 -0
  187. package/src/components/Editor/EditorPreviewPane/EditorPreview.js +40 -0
  188. package/src/components/Editor/EditorPreviewPane/EditorPreviewContent.js +74 -0
  189. package/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js +333 -0
  190. package/src/components/Editor/EditorPreviewPane/PreviewHOC.js +33 -0
  191. package/src/components/Editor/EditorToolbar.js +691 -0
  192. package/src/components/Editor/__tests__/Editor.spec.js +221 -0
  193. package/src/components/Editor/__tests__/EditorToolbar.spec.js +120 -0
  194. package/src/components/Editor/__tests__/__snapshots__/Editor.spec.js.snap +45 -0
  195. package/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap +4233 -0
  196. package/src/components/Editor/withWorkflow.js +61 -0
  197. package/src/components/EditorWidgets/Unknown/UnknownControl.js +17 -0
  198. package/src/components/EditorWidgets/Unknown/UnknownPreview.js +19 -0
  199. package/src/components/EditorWidgets/index.js +5 -0
  200. package/src/components/MediaLibrary/EmptyMessage.js +28 -0
  201. package/src/components/MediaLibrary/MediaLibrary.js +411 -0
  202. package/src/components/MediaLibrary/MediaLibraryButtons.js +136 -0
  203. package/src/components/MediaLibrary/MediaLibraryCard.js +128 -0
  204. package/src/components/MediaLibrary/MediaLibraryCardGrid.js +199 -0
  205. package/src/components/MediaLibrary/MediaLibraryHeader.js +48 -0
  206. package/src/components/MediaLibrary/MediaLibraryModal.js +200 -0
  207. package/src/components/MediaLibrary/MediaLibrarySearch.js +61 -0
  208. package/src/components/MediaLibrary/MediaLibraryTop.js +143 -0
  209. package/src/components/MediaLibrary/__tests__/MediaLibraryButtons.spec.js +45 -0
  210. package/src/components/MediaLibrary/__tests__/MediaLibraryCard.spec.js +49 -0
  211. package/src/components/MediaLibrary/__tests__/__snapshots__/MediaLibraryCard.spec.js.snap +264 -0
  212. package/src/components/UI/DragDrop.js +66 -0
  213. package/src/components/UI/ErrorBoundary.js +214 -0
  214. package/src/components/UI/FileUploadButton.js +24 -0
  215. package/src/components/UI/Modal.js +112 -0
  216. package/src/components/UI/Notifications.tsx +83 -0
  217. package/src/components/UI/SettingsDropdown.js +103 -0
  218. package/src/components/UI/__tests__/ErrorBoundary.spec.js +57 -0
  219. package/src/components/UI/index.js +6 -0
  220. package/src/components/Workflow/Workflow.js +169 -0
  221. package/src/components/Workflow/WorkflowCard.js +177 -0
  222. package/src/components/Workflow/WorkflowList.js +272 -0
  223. package/src/constants/__tests__/configSchema.spec.js +611 -0
  224. package/src/constants/collectionTypes.ts +2 -0
  225. package/src/constants/collectionViews.js +2 -0
  226. package/src/constants/commitProps.ts +2 -0
  227. package/src/constants/configSchema.js +441 -0
  228. package/src/constants/fieldInference.tsx +78 -0
  229. package/src/constants/publishModes.ts +22 -0
  230. package/src/constants/validationErrorTypes.js +6 -0
  231. package/src/formats/__tests__/formats.spec.js +87 -0
  232. package/src/formats/__tests__/frontmatter.spec.js +429 -0
  233. package/src/formats/__tests__/toml.spec.js +9 -0
  234. package/src/formats/__tests__/yaml.spec.js +162 -0
  235. package/src/formats/formats.ts +97 -0
  236. package/src/formats/frontmatter.ts +150 -0
  237. package/src/formats/helpers.ts +14 -0
  238. package/src/formats/json.ts +9 -0
  239. package/src/formats/toml.ts +33 -0
  240. package/src/formats/yaml.ts +58 -0
  241. package/src/index.js +8 -0
  242. package/src/integrations/index.js +35 -0
  243. package/src/integrations/providers/algolia/implementation.js +176 -0
  244. package/src/integrations/providers/assetStore/implementation.js +148 -0
  245. package/src/lib/__tests__/formatters.spec.js +751 -0
  246. package/src/lib/__tests__/i18n.spec.js +792 -0
  247. package/src/lib/__tests__/phrases.spec.js +119 -0
  248. package/src/lib/__tests__/registry.spec.js +261 -0
  249. package/src/lib/__tests__/serializeEntryValues.spec.js +22 -0
  250. package/src/lib/__tests__/urlHelper.spec.js +138 -0
  251. package/src/lib/consoleError.js +7 -0
  252. package/src/lib/formatters.ts +286 -0
  253. package/src/lib/i18n.ts +454 -0
  254. package/src/lib/phrases.js +8 -0
  255. package/src/lib/polyfill.js +9 -0
  256. package/src/lib/registry.js +312 -0
  257. package/src/lib/serializeEntryValues.js +75 -0
  258. package/src/lib/stega.ts +145 -0
  259. package/src/lib/textHelper.js +11 -0
  260. package/src/lib/urlHelper.ts +128 -0
  261. package/src/mediaLibrary.ts +51 -0
  262. package/src/reducers/__tests__/auth.spec.ts +38 -0
  263. package/src/reducers/__tests__/collections.spec.js +610 -0
  264. package/src/reducers/__tests__/config.spec.js +38 -0
  265. package/src/reducers/__tests__/entries.spec.js +694 -0
  266. package/src/reducers/__tests__/entryDraft.spec.js +297 -0
  267. package/src/reducers/__tests__/globalUI.js +43 -0
  268. package/src/reducers/__tests__/integrations.spec.ts +76 -0
  269. package/src/reducers/__tests__/mediaLibrary.spec.js +154 -0
  270. package/src/reducers/__tests__/medias.spec.ts +49 -0
  271. package/src/reducers/auth.ts +46 -0
  272. package/src/reducers/collections.ts +535 -0
  273. package/src/reducers/combinedReducer.ts +11 -0
  274. package/src/reducers/config.ts +38 -0
  275. package/src/reducers/cursors.js +36 -0
  276. package/src/reducers/deploys.ts +52 -0
  277. package/src/reducers/editorialWorkflow.ts +163 -0
  278. package/src/reducers/entries.ts +819 -0
  279. package/src/reducers/entryDraft.js +260 -0
  280. package/src/reducers/globalUI.ts +45 -0
  281. package/src/reducers/index.ts +82 -0
  282. package/src/reducers/integrations.ts +59 -0
  283. package/src/reducers/mediaLibrary.ts +296 -0
  284. package/src/reducers/medias.ts +66 -0
  285. package/src/reducers/notifications.ts +52 -0
  286. package/src/reducers/search.ts +111 -0
  287. package/src/reducers/status.ts +40 -0
  288. package/src/redux/index.ts +18 -0
  289. package/src/redux/middleware/waitUntilAction.ts +64 -0
  290. package/src/routing/__tests__/history.spec.ts +49 -0
  291. package/src/routing/history.ts +17 -0
  292. package/src/types/diacritics.d.ts +1 -0
  293. package/src/types/global.d.ts +8 -0
  294. package/src/types/immutable.ts +49 -0
  295. package/src/types/redux.ts +827 -0
  296. package/src/types/tomlify-j0.4.d.ts +13 -0
  297. package/src/valueObjects/AssetProxy.ts +48 -0
  298. package/src/valueObjects/EditorComponent.js +38 -0
  299. package/src/valueObjects/Entry.ts +63 -0
@@ -0,0 +1,596 @@
1
+ import { fromJS, Map } from 'immutable';
2
+ import configureMockStore from 'redux-mock-store';
3
+ import thunk from 'redux-thunk';
4
+
5
+ import {
6
+ createEmptyDraft,
7
+ createEmptyDraftData,
8
+ retrieveLocalBackup,
9
+ persistLocalBackup,
10
+ getMediaAssets,
11
+ validateMetaField,
12
+ } from '../entries';
13
+ import AssetProxy from '../../valueObjects/AssetProxy';
14
+
15
+ jest.mock('../../backend');
16
+ jest.mock('decap-cms-lib-util');
17
+ jest.mock('../mediaLibrary');
18
+ jest.mock('../../reducers/entries');
19
+ jest.mock('../../reducers/entryDraft');
20
+
21
+ const middlewares = [thunk];
22
+ const mockStore = configureMockStore(middlewares);
23
+
24
+ describe('entries', () => {
25
+ describe('createEmptyDraft', () => {
26
+ const { currentBackend } = require('../../backend');
27
+ const backend = {
28
+ processEntry: jest.fn((_state, _collection, entry) => Promise.resolve(entry)),
29
+ };
30
+
31
+ currentBackend.mockReturnValue(backend);
32
+
33
+ beforeEach(() => {
34
+ jest.clearAllMocks();
35
+ });
36
+ it('should dispatch draft created action', () => {
37
+ const store = mockStore({ mediaLibrary: fromJS({ files: [] }) });
38
+
39
+ const collection = fromJS({
40
+ fields: [{ name: 'title' }],
41
+ });
42
+
43
+ return store.dispatch(createEmptyDraft(collection, '')).then(() => {
44
+ const actions = store.getActions();
45
+ expect(actions).toHaveLength(1);
46
+
47
+ expect(actions[0]).toEqual({
48
+ payload: {
49
+ author: '',
50
+ collection: undefined,
51
+ data: {},
52
+ meta: {},
53
+ i18n: {},
54
+ isModification: null,
55
+ label: null,
56
+ mediaFiles: [],
57
+ partial: false,
58
+ path: '',
59
+ raw: '',
60
+ slug: '',
61
+ status: '',
62
+ updatedOn: '',
63
+ },
64
+ type: 'DRAFT_CREATE_EMPTY',
65
+ });
66
+ });
67
+ });
68
+
69
+ it('should populate draft entry from URL param', () => {
70
+ const store = mockStore({ mediaLibrary: fromJS({ files: [] }) });
71
+
72
+ const collection = fromJS({
73
+ fields: [{ name: 'title' }, { name: 'boolean' }],
74
+ });
75
+
76
+ return store.dispatch(createEmptyDraft(collection, '?title=title&boolean=True')).then(() => {
77
+ const actions = store.getActions();
78
+ expect(actions).toHaveLength(1);
79
+
80
+ expect(actions[0]).toEqual({
81
+ payload: {
82
+ author: '',
83
+ collection: undefined,
84
+ data: { title: 'title', boolean: true },
85
+ meta: {},
86
+ i18n: {},
87
+ isModification: null,
88
+ label: null,
89
+ mediaFiles: [],
90
+ partial: false,
91
+ path: '',
92
+ raw: '',
93
+ slug: '',
94
+ status: '',
95
+ updatedOn: '',
96
+ },
97
+ type: 'DRAFT_CREATE_EMPTY',
98
+ });
99
+ });
100
+ });
101
+
102
+ it('should html escape URL params', () => {
103
+ const store = mockStore({ mediaLibrary: fromJS({ files: [] }) });
104
+
105
+ const collection = fromJS({
106
+ fields: [{ name: 'title' }],
107
+ });
108
+
109
+ return store
110
+ .dispatch(createEmptyDraft(collection, "?title=<script>alert('hello')</script>"))
111
+ .then(() => {
112
+ const actions = store.getActions();
113
+ expect(actions).toHaveLength(1);
114
+
115
+ expect(actions[0]).toEqual({
116
+ payload: {
117
+ author: '',
118
+ collection: undefined,
119
+ data: { title: '&lt;script&gt;alert(&#039;hello&#039;)&lt;/script&gt;' },
120
+ meta: {},
121
+ i18n: {},
122
+ isModification: null,
123
+ label: null,
124
+ mediaFiles: [],
125
+ partial: false,
126
+ path: '',
127
+ raw: '',
128
+ slug: '',
129
+ status: '',
130
+ updatedOn: '',
131
+ },
132
+ type: 'DRAFT_CREATE_EMPTY',
133
+ });
134
+ });
135
+ });
136
+ });
137
+ describe('createEmptyDraftData', () => {
138
+ it('should allow an empty array as list default for a single field list', () => {
139
+ const fields = fromJS([
140
+ {
141
+ name: 'images',
142
+ widget: 'list',
143
+ default: [],
144
+ field: { name: 'url', widget: 'text' },
145
+ },
146
+ ]);
147
+ expect(createEmptyDraftData(fields)).toEqual({ images: fromJS([]) });
148
+ });
149
+
150
+ it('should allow a complex array as list default for a single field list', () => {
151
+ const fields = fromJS([
152
+ {
153
+ name: 'images',
154
+ widget: 'list',
155
+ default: [
156
+ {
157
+ url: 'https://image.png',
158
+ },
159
+ ],
160
+ field: { name: 'url', widget: 'text' },
161
+ },
162
+ ]);
163
+ expect(createEmptyDraftData(fields)).toEqual({
164
+ images: fromJS([
165
+ {
166
+ url: 'https://image.png',
167
+ },
168
+ ]),
169
+ });
170
+ });
171
+
172
+ it('should allow an empty array as list default for a fields list', () => {
173
+ const fields = fromJS([
174
+ {
175
+ name: 'images',
176
+ widget: 'list',
177
+ default: [],
178
+ fields: [
179
+ { name: 'title', widget: 'text' },
180
+ { name: 'url', widget: 'text' },
181
+ ],
182
+ },
183
+ ]);
184
+ expect(createEmptyDraftData(fields)).toEqual({ images: fromJS([]) });
185
+ });
186
+
187
+ it('should allow a complex array as list default for a fields list', () => {
188
+ const fields = fromJS([
189
+ {
190
+ name: 'images',
191
+ widget: 'list',
192
+ default: [
193
+ {
194
+ title: 'default image',
195
+ url: 'https://image.png',
196
+ },
197
+ ],
198
+ fields: [
199
+ { name: 'title', widget: 'text' },
200
+ { name: 'url', widget: 'text' },
201
+ ],
202
+ },
203
+ ]);
204
+ expect(createEmptyDraftData(fields)).toEqual({
205
+ images: fromJS([
206
+ {
207
+ title: 'default image',
208
+ url: 'https://image.png',
209
+ },
210
+ ]),
211
+ });
212
+ });
213
+
214
+ it('should use field default when no list default is provided', () => {
215
+ const fields = fromJS([
216
+ {
217
+ name: 'images',
218
+ widget: 'list',
219
+ field: { name: 'url', widget: 'text', default: 'https://image.png' },
220
+ },
221
+ ]);
222
+ expect(createEmptyDraftData(fields)).toEqual({ images: [{ url: 'https://image.png' }] });
223
+ });
224
+
225
+ it('should use fields default when no list default is provided', () => {
226
+ const fields = fromJS([
227
+ {
228
+ name: 'images',
229
+ widget: 'list',
230
+ fields: [
231
+ { name: 'title', widget: 'text', default: 'default image' },
232
+ { name: 'url', widget: 'text', default: 'https://image.png' },
233
+ ],
234
+ },
235
+ ]);
236
+ expect(createEmptyDraftData(fields)).toEqual({
237
+ images: [{ title: 'default image', url: 'https://image.png' }],
238
+ });
239
+ });
240
+
241
+ it('should not set empty value for list fields widget', () => {
242
+ const fields = fromJS([
243
+ {
244
+ name: 'images',
245
+ widget: 'list',
246
+ fields: [
247
+ { name: 'title', widget: 'text' },
248
+ { name: 'url', widget: 'text' },
249
+ ],
250
+ },
251
+ ]);
252
+ expect(createEmptyDraftData(fields)).toEqual({});
253
+ });
254
+
255
+ it('should set default value for object field widget', () => {
256
+ const fields = fromJS([
257
+ {
258
+ name: 'post',
259
+ widget: 'object',
260
+ field: { name: 'image', widget: 'text', default: 'https://image.png' },
261
+ },
262
+ ]);
263
+ expect(createEmptyDraftData(fields)).toEqual({ post: { image: 'https://image.png' } });
264
+ });
265
+
266
+ it('should set default values for object fields widget', () => {
267
+ const fields = fromJS([
268
+ {
269
+ name: 'post',
270
+ widget: 'object',
271
+ fields: [
272
+ { name: 'title', widget: 'text', default: 'default title' },
273
+ { name: 'url', widget: 'text', default: 'https://image.png' },
274
+ ],
275
+ },
276
+ ]);
277
+ expect(createEmptyDraftData(fields)).toEqual({
278
+ post: { title: 'default title', url: 'https://image.png' },
279
+ });
280
+ });
281
+
282
+ it('should not set empty value for object fields widget', () => {
283
+ const fields = fromJS([
284
+ {
285
+ name: 'post',
286
+ widget: 'object',
287
+ fields: [
288
+ { name: 'title', widget: 'text' },
289
+ { name: 'url', widget: 'text' },
290
+ ],
291
+ },
292
+ ]);
293
+ expect(createEmptyDraftData(fields)).toEqual({});
294
+ });
295
+
296
+ it('should populate nested fields', () => {
297
+ const fields = fromJS([
298
+ {
299
+ name: 'names',
300
+ widget: 'list',
301
+ field: {
302
+ name: 'object',
303
+ widget: 'object',
304
+ fields: [
305
+ { name: 'first', widget: 'string', default: 'first' },
306
+ { name: 'second', widget: 'string', default: 'second' },
307
+ ],
308
+ },
309
+ },
310
+ ]);
311
+ expect(createEmptyDraftData(fields)).toEqual({
312
+ names: [{ object: { first: 'first', second: 'second' } }],
313
+ });
314
+ });
315
+ });
316
+
317
+ describe('persistLocalBackup', () => {
318
+ beforeEach(() => {
319
+ jest.clearAllMocks();
320
+ });
321
+
322
+ it('should persist local backup with media files', () => {
323
+ const { currentBackend } = require('../../backend');
324
+
325
+ const backend = {
326
+ persistLocalDraftBackup: jest.fn(() => Promise.resolve()),
327
+ };
328
+
329
+ const store = mockStore({
330
+ config: Map(),
331
+ });
332
+
333
+ currentBackend.mockReturnValue(backend);
334
+
335
+ const collection = Map();
336
+ const mediaFiles = [{ path: 'static/media/image.png' }];
337
+ const entry = fromJS({ mediaFiles });
338
+
339
+ return store.dispatch(persistLocalBackup(entry, collection)).then(() => {
340
+ const actions = store.getActions();
341
+ expect(actions).toHaveLength(0);
342
+
343
+ expect(backend.persistLocalDraftBackup).toHaveBeenCalledTimes(1);
344
+ expect(backend.persistLocalDraftBackup).toHaveBeenCalledWith(entry, collection);
345
+ });
346
+ });
347
+ });
348
+
349
+ describe('retrieveLocalBackup', () => {
350
+ beforeEach(() => {
351
+ jest.clearAllMocks();
352
+ });
353
+
354
+ it('should retrieve media files with local backup', () => {
355
+ const { currentBackend } = require('../../backend');
356
+ const { createAssetProxy } = require('../../valueObjects/AssetProxy');
357
+
358
+ const backend = {
359
+ getLocalDraftBackup: jest.fn((...args) => args),
360
+ };
361
+
362
+ const store = mockStore({
363
+ config: Map(),
364
+ });
365
+
366
+ currentBackend.mockReturnValue(backend);
367
+
368
+ const collection = Map({
369
+ name: 'collection',
370
+ });
371
+ const slug = 'slug';
372
+
373
+ const file = new File([], 'image.png');
374
+ const mediaFiles = [{ path: 'static/media/image.png', url: 'url', file }];
375
+ const asset = createAssetProxy(mediaFiles[0]);
376
+ const entry = { mediaFiles };
377
+
378
+ backend.getLocalDraftBackup.mockReturnValue({ entry });
379
+
380
+ return store.dispatch(retrieveLocalBackup(collection, slug)).then(() => {
381
+ const actions = store.getActions();
382
+
383
+ expect(actions).toHaveLength(2);
384
+
385
+ expect(actions[0]).toEqual({
386
+ type: 'ADD_ASSETS',
387
+ payload: [asset],
388
+ });
389
+ expect(actions[1]).toEqual({
390
+ type: 'DRAFT_LOCAL_BACKUP_RETRIEVED',
391
+ payload: { entry },
392
+ });
393
+ });
394
+ });
395
+ });
396
+
397
+ describe('getMediaAssets', () => {
398
+ beforeEach(() => {
399
+ jest.clearAllMocks();
400
+ });
401
+
402
+ it('should map mediaFiles to assets', () => {
403
+ const mediaFiles = fromJS([{ path: 'path1' }, { path: 'path2', draft: true }]);
404
+
405
+ const entry = Map({ mediaFiles });
406
+ expect(getMediaAssets({ entry })).toEqual([new AssetProxy({ path: 'path2' })]);
407
+ });
408
+ });
409
+
410
+ describe('validateMetaField', () => {
411
+ const state = {
412
+ config: {
413
+ slug: {
414
+ encoding: 'unicode',
415
+ clean_accents: false,
416
+ sanitize_replacement: '-',
417
+ },
418
+ },
419
+ entries: fromJS([]),
420
+ };
421
+ const collection = fromJS({
422
+ folder: 'folder',
423
+ type: 'folder_based_collection',
424
+ name: 'name',
425
+ });
426
+ const t = jest.fn((key, args) => ({ key, args }));
427
+
428
+ const { selectCustomPath } = require('../../reducers/entryDraft');
429
+ const { selectEntryByPath } = require('../../reducers/entries');
430
+
431
+ beforeEach(() => {
432
+ jest.clearAllMocks();
433
+ });
434
+
435
+ it('should not return error on non meta field', () => {
436
+ expect(validateMetaField(null, null, fromJS({}), null, t)).toEqual({ error: false });
437
+ });
438
+
439
+ it('should not return error on meta path field', () => {
440
+ expect(validateMetaField(null, null, fromJS({ meta: true, name: 'other' }), null, t)).toEqual(
441
+ { error: false },
442
+ );
443
+ });
444
+
445
+ it('should return error on empty path', () => {
446
+ expect(validateMetaField(null, null, fromJS({ meta: true, name: 'path' }), null, t)).toEqual({
447
+ error: {
448
+ message: {
449
+ key: 'editor.editorControlPane.widget.invalidPath',
450
+ args: { path: null },
451
+ },
452
+ type: 'CUSTOM',
453
+ },
454
+ });
455
+
456
+ expect(
457
+ validateMetaField(null, null, fromJS({ meta: true, name: 'path' }), undefined, t),
458
+ ).toEqual({
459
+ error: {
460
+ message: {
461
+ key: 'editor.editorControlPane.widget.invalidPath',
462
+ args: { path: undefined },
463
+ },
464
+ type: 'CUSTOM',
465
+ },
466
+ });
467
+
468
+ expect(validateMetaField(null, null, fromJS({ meta: true, name: 'path' }), '', t)).toEqual({
469
+ error: {
470
+ message: {
471
+ key: 'editor.editorControlPane.widget.invalidPath',
472
+ args: { path: '' },
473
+ },
474
+ type: 'CUSTOM',
475
+ },
476
+ });
477
+ });
478
+
479
+ it('should return error on invalid path', () => {
480
+ expect(
481
+ validateMetaField(state, null, fromJS({ meta: true, name: 'path' }), 'invalid path', t),
482
+ ).toEqual({
483
+ error: {
484
+ message: {
485
+ key: 'editor.editorControlPane.widget.invalidPath',
486
+ args: { path: 'invalid path' },
487
+ },
488
+ type: 'CUSTOM',
489
+ },
490
+ });
491
+ });
492
+
493
+ it('should return error on existing path', () => {
494
+ selectCustomPath.mockReturnValue('existing-path');
495
+ selectEntryByPath.mockReturnValue(fromJS({ path: 'existing-path' }));
496
+ expect(
497
+ validateMetaField(
498
+ {
499
+ ...state,
500
+ entryDraft: fromJS({
501
+ entry: {},
502
+ }),
503
+ },
504
+ collection,
505
+ fromJS({ meta: true, name: 'path' }),
506
+ 'existing-path',
507
+ t,
508
+ ),
509
+ ).toEqual({
510
+ error: {
511
+ message: {
512
+ key: 'editor.editorControlPane.widget.pathExists',
513
+ args: { path: 'existing-path' },
514
+ },
515
+ type: 'CUSTOM',
516
+ },
517
+ });
518
+
519
+ expect(selectCustomPath).toHaveBeenCalledTimes(1);
520
+ expect(selectCustomPath).toHaveBeenCalledWith(
521
+ collection,
522
+ fromJS({ entry: { meta: { path: 'existing-path' } } }),
523
+ );
524
+
525
+ expect(selectEntryByPath).toHaveBeenCalledTimes(1);
526
+ expect(selectEntryByPath).toHaveBeenCalledWith(
527
+ state.entries,
528
+ collection.get('name'),
529
+ 'existing-path',
530
+ );
531
+ });
532
+
533
+ it('should not return error on non existing path for new entry', () => {
534
+ selectCustomPath.mockReturnValue('non-existing-path');
535
+ selectEntryByPath.mockReturnValue(undefined);
536
+ expect(
537
+ validateMetaField(
538
+ {
539
+ ...state,
540
+ entryDraft: fromJS({
541
+ entry: {},
542
+ }),
543
+ },
544
+ collection,
545
+ fromJS({ meta: true, name: 'path' }),
546
+ 'non-existing-path',
547
+ t,
548
+ ),
549
+ ).toEqual({
550
+ error: false,
551
+ });
552
+ });
553
+
554
+ it('should not return error when for existing entry', () => {
555
+ selectCustomPath.mockReturnValue('existing-path');
556
+ selectEntryByPath.mockReturnValue(fromJS({ path: 'existing-path' }));
557
+ expect(
558
+ validateMetaField(
559
+ {
560
+ ...state,
561
+ entryDraft: fromJS({
562
+ entry: { path: 'existing-path' },
563
+ }),
564
+ },
565
+ collection,
566
+ fromJS({ meta: true, name: 'path' }),
567
+ 'existing-path',
568
+ t,
569
+ ),
570
+ ).toEqual({
571
+ error: false,
572
+ });
573
+ });
574
+
575
+ it('should not return error on path with capital letters', () => {
576
+ selectCustomPath.mockReturnValue('4-Meteor/6-Cloud-Folders');
577
+ selectEntryByPath.mockReturnValue(undefined);
578
+ expect(
579
+ validateMetaField(
580
+ {
581
+ ...state,
582
+ entryDraft: fromJS({
583
+ entry: {},
584
+ }),
585
+ },
586
+ collection,
587
+ fromJS({ meta: true, name: 'path' }),
588
+ '4-Meteor/6-Cloud-Folders',
589
+ t,
590
+ ),
591
+ ).toEqual({
592
+ error: false,
593
+ });
594
+ });
595
+ });
596
+ });