@elementor/editor-documents 0.11.4 → 0.11.6

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.
@@ -1,463 +0,0 @@
1
- import { syncStore } from '../index';
2
- import { slice } from '../../store';
3
- import { ExtendedWindow, V1Document, Document, ExitTo } from '../../types';
4
- import { __createStore, __registerSlice, SliceState, Store } from '@elementor/store';
5
- import {
6
- dispatchCommandAfter,
7
- dispatchCommandBefore,
8
- dispatchV1ReadyEvent,
9
- makeDocumentsManager,
10
- makeMockV1Document,
11
- } from './test-utils';
12
- import { selectActiveDocument } from '../../store/selectors';
13
- import { getV1DocumentPermalink, getV1DocumentsExitTo } from '../utils';
14
-
15
- type WindowWithOptionalElementor = Omit<ExtendedWindow, 'elementor'> & {
16
- elementor?: ExtendedWindow['elementor'];
17
- }
18
-
19
- describe( '@elementor/editor-documents - Sync Store', () => {
20
- let store: Store<SliceState<typeof slice>>;
21
-
22
- beforeEach( () => {
23
- jest.useFakeTimers();
24
-
25
- __registerSlice( slice );
26
- store = __createStore();
27
-
28
- syncStore();
29
- } );
30
-
31
- afterEach( () => {
32
- jest.useRealTimers();
33
- } );
34
-
35
- it( 'should sync documents on V1 load', () => {
36
- // Arrange.
37
- mockV1DocumentsManager( [
38
- makeMockV1Document( { id: 1 } ),
39
- makeMockV1Document( { id: 2 } ),
40
- ], 'this_post' );
41
-
42
- // Act.
43
- dispatchV1ReadyEvent();
44
-
45
- // Assert.
46
- const storeState = store.getState();
47
-
48
- expect( storeState.documents.entities ).toEqual<Record<number, Document>>( {
49
- 1: {
50
- id: 1,
51
- title: 'Document 1',
52
- type: {
53
- value: 'wp-page',
54
- label: 'WP-PAGE',
55
- },
56
- status: {
57
- value: 'publish',
58
- label: 'PUBLISH',
59
- },
60
- links: {
61
- platformEdit: 'https://localhost/wp-admin/post.php?post=1&action=edit',
62
- permalink: 'https://localhost/?p=1',
63
- },
64
- isDirty: false,
65
- isSaving: false,
66
- isSavingDraft: false,
67
- userCan: {
68
- publish: true,
69
- },
70
- permissions: {
71
- allowAddingWidgets: true,
72
- showCopyAndShare: false,
73
- },
74
- },
75
- 2: {
76
- id: 2,
77
- title: 'Document 2',
78
- type: {
79
- value: 'wp-page',
80
- label: 'WP-PAGE',
81
- },
82
- status: {
83
- value: 'publish',
84
- label: 'PUBLISH',
85
- },
86
- links: {
87
- platformEdit: 'https://localhost/wp-admin/post.php?post=2&action=edit',
88
- permalink: 'https://localhost/?p=2',
89
- },
90
- isDirty: false,
91
- isSaving: false,
92
- isSavingDraft: false,
93
- userCan: {
94
- publish: true,
95
- },
96
- permissions: {
97
- allowAddingWidgets: true,
98
- showCopyAndShare: false,
99
- },
100
- },
101
- } );
102
- } );
103
-
104
- it.each( [
105
- {
106
- type: 'V1 load',
107
- dispatchEvent: () => dispatchV1ReadyEvent(),
108
- },
109
- {
110
- type: 'document open',
111
- dispatchEvent: () => dispatchCommandAfter( 'editor/documents/open' ),
112
- },
113
- ] )( 'should sync active document on $type', ( { dispatchEvent } ) => {
114
- // Arrange.
115
- mockV1DocumentsManager( [
116
- makeMockV1Document( { id: 1 } ),
117
- makeMockV1Document( { id: 2 } ),
118
- ], 'this_post', 2 );
119
-
120
- // Act.
121
- dispatchEvent();
122
-
123
- // Assert.
124
- const currentDocument = selectActiveDocument( store.getState() );
125
-
126
- expect( currentDocument ).toEqual<Document>( {
127
- id: 2,
128
- title: 'Document 2',
129
- type: {
130
- value: 'wp-page',
131
- label: 'WP-PAGE',
132
- },
133
- links: {
134
- platformEdit: 'https://localhost/wp-admin/post.php?post=2&action=edit',
135
- permalink: 'https://localhost/?p=2',
136
- },
137
- status: {
138
- value: 'publish',
139
- label: 'PUBLISH',
140
- },
141
- isDirty: false,
142
- isSaving: false,
143
- isSavingDraft: false,
144
- userCan: {
145
- publish: true,
146
- },
147
- permissions: {
148
- allowAddingWidgets: true,
149
- showCopyAndShare: false,
150
- },
151
- } );
152
- } );
153
-
154
- it.each( [
155
- {
156
- openAsHost: true,
157
- expectedHost: 2,
158
- },
159
- {
160
- openAsHost: false,
161
- expectedHost: 1,
162
- },
163
- ] )( 'should sync host document when a new host is opened { openAsHost: $openAsHost }', ( { openAsHost, expectedHost } ) => {
164
- // Arrange.
165
- const mockDocument1 = makeMockV1Document( { id: 1 } );
166
- const mockDocument2 = makeMockV1Document( { id: 2 } );
167
-
168
- mockV1DocumentsManager( [
169
- mockDocument1,
170
- mockDocument2,
171
- ], 'this_post', 1, 1 );
172
-
173
- // Populate the documents state.
174
- dispatchV1ReadyEvent();
175
-
176
- // Act - Mock a host document change.
177
- mockV1DocumentsManager( [
178
- mockDocument1,
179
- mockDocument2,
180
- ], 'this_post', 2, openAsHost ? 2 : 1 );
181
-
182
- dispatchCommandAfter( 'editor/documents/open' );
183
-
184
- // Assert.
185
- expect( store.getState().documents.hostId ).toBe( expectedHost );
186
- } );
187
-
188
- it( 'should sync saving state of a document on V1 load', () => {
189
- // Arrange.
190
- const mockDocument = makeMockV1Document();
191
-
192
- mockV1DocumentsManager( [
193
- {
194
- ...mockDocument,
195
- editor: {
196
- ...mockDocument.editor,
197
- isSaving: true,
198
- },
199
- },
200
- ] );
201
-
202
- // Act.
203
- dispatchV1ReadyEvent();
204
-
205
- // Assert.
206
- expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( true );
207
- } );
208
-
209
- it( 'should sync saving state of a document on save', () => {
210
- // Arrange.
211
- mockV1DocumentsManager( [
212
- makeMockV1Document(),
213
- ] );
214
-
215
- // Populate the documents state.
216
- dispatchV1ReadyEvent();
217
-
218
- // Assert - Default state.
219
- expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( false );
220
-
221
- // Act.
222
- dispatchCommandBefore( 'document/save/save' );
223
-
224
- // Assert - On save start.
225
- expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( true );
226
- expect( selectActiveDocument( store.getState() )?.isSavingDraft ).toBe( false );
227
-
228
- // Act.
229
- dispatchCommandAfter( 'document/save/save' );
230
-
231
- // Assert - On save end.
232
- expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( false );
233
- expect( selectActiveDocument( store.getState() )?.isSavingDraft ).toBe( false );
234
- } );
235
-
236
- it( 'should sync draft saving state of a document on save', () => {
237
- // Arrange.
238
- mockV1DocumentsManager( [
239
- makeMockV1Document(),
240
- ] );
241
-
242
- // Populate the documents state.
243
- dispatchV1ReadyEvent();
244
-
245
- // Assert - Default state.
246
- expect( selectActiveDocument( store.getState() )?.isSavingDraft ).toBe( false );
247
-
248
- // Act.
249
- dispatchCommandBefore( 'document/save/save', {
250
- status: 'autosave',
251
- } );
252
-
253
- // Assert - On save start.
254
- expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( false );
255
- expect( selectActiveDocument( store.getState() )?.isSavingDraft ).toBe( true );
256
-
257
- // Act.
258
- dispatchCommandAfter( 'document/save/save', {
259
- status: 'autosave',
260
- } );
261
-
262
- // Assert - On save end.
263
- expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( false );
264
- expect( selectActiveDocument( store.getState() )?.isSavingDraft ).toBe( false );
265
- } );
266
-
267
- it( 'should sync dirty state of a document when it has an autosave', () => {
268
- // Arrange.
269
- const mockDocument = makeMockV1Document( { id: 1 } );
270
-
271
- mockV1DocumentsManager( [ {
272
- ...mockDocument,
273
- config: {
274
- ...mockDocument.config,
275
- revisions: {
276
- current_id: 2,
277
- },
278
- },
279
- } ] );
280
-
281
- // Act.
282
- dispatchV1ReadyEvent();
283
-
284
- // Assert.
285
- expect( selectActiveDocument( store.getState() )?.isDirty ).toBe( true );
286
- } );
287
-
288
- it( 'should sync dirty state of a document on document change', () => {
289
- // Arrange.
290
- const mockDocument = makeMockV1Document();
291
-
292
- mockV1DocumentsManager( [
293
- mockDocument,
294
- ] );
295
-
296
- // Populate the documents state.
297
- dispatchV1ReadyEvent();
298
-
299
- // Mock a change.
300
- mockDocument.editor.isChanged = true;
301
-
302
- // Assert - Default state.
303
- expect( selectActiveDocument( store.getState() )?.isDirty ).toBe( false );
304
-
305
- // Act.
306
- dispatchCommandAfter( 'document/save/set-is-modified' );
307
-
308
- // Assert - After change.
309
- expect( selectActiveDocument( store.getState() )?.isDirty ).toBe( true );
310
-
311
- // Emulate a save / undo action that flips the `isChanged` back to `false`.
312
- mockDocument.editor.isChanged = false;
313
-
314
- dispatchCommandAfter( 'document/save/set-is-modified' );
315
-
316
- // Assert - After change.
317
- expect( selectActiveDocument( store.getState() )?.isDirty ).toBe( false );
318
- } );
319
-
320
- it( 'should sync document title on V1 setting change', () => {
321
- // Arrange.
322
- mockV1DocumentsManager( [
323
- makeMockV1Document( {
324
- title: 'old title',
325
- } ),
326
- ] );
327
-
328
- // Populate the documents state.
329
- dispatchV1ReadyEvent();
330
-
331
- // Act - simulate a change.
332
- mockV1DocumentsManager( [
333
- makeMockV1Document( {
334
- title: 'new title',
335
- } ),
336
- ] );
337
-
338
- dispatchCommandAfter( 'document/elements/settings', {
339
- settings: {
340
- post_title: 'new title',
341
- },
342
- } );
343
-
344
- jest.runAllTimers();
345
-
346
- // Assert.
347
- expect( selectActiveDocument( store.getState() )?.title ).toBe( 'new title' );
348
- } );
349
-
350
- it( 'should not sync document title when a non-related V1 setting has changed', () => {
351
- // Arrange.
352
- mockV1DocumentsManager( [
353
- makeMockV1Document( {
354
- title: 'old title',
355
- } ),
356
- ] );
357
-
358
- // Populate the documents state.
359
- dispatchV1ReadyEvent();
360
-
361
- // Act - simulate a change.
362
- dispatchCommandAfter( 'document/elements/settings', {
363
- settings: {
364
- nonRelated: 'value',
365
- },
366
- } );
367
-
368
- jest.runAllTimers();
369
-
370
- // Assert.
371
- expect( selectActiveDocument( store.getState() )?.title ).toBe( 'old title' );
372
- } );
373
-
374
- it( 'should update the document when finish saving', () => {
375
- // Arrange.
376
- mockV1DocumentsManager( [
377
- makeMockV1Document( {
378
- id: 1,
379
- status: 'draft',
380
- title: 'test',
381
- } ),
382
- ], 'this_post' );
383
-
384
- // Populate the documents state.
385
- dispatchV1ReadyEvent();
386
-
387
- // Mock a change.
388
- mockV1DocumentsManager( [
389
- makeMockV1Document( {
390
- id: 1,
391
- status: 'publish',
392
- title: 'test title changed',
393
- } ),
394
- ], 'dashboard' );
395
-
396
- // Assert.
397
- expect( selectActiveDocument( store.getState() )?.title ).toBe( 'test' );
398
- expect( selectActiveDocument( store.getState() )?.status.value ).toBe( 'draft' );
399
- expect( selectActiveDocument( store.getState() )?.links.platformEdit ).toBe( 'https://localhost/wp-admin/post.php?post=1&action=edit' );
400
-
401
- // Act.
402
- dispatchCommandAfter( 'document/save/save' );
403
-
404
- // Assert.
405
- expect( selectActiveDocument( store.getState() )?.title ).toBe( 'test title changed' );
406
- expect( selectActiveDocument( store.getState() )?.status.value ).toBe( 'publish' );
407
- expect( selectActiveDocument( store.getState() )?.links.platformEdit ).toBe( 'https://localhost/wp-admin/' );
408
- } );
409
-
410
- it.each( [
411
- 'dashboard',
412
- 'this_post',
413
- 'all_posts',
414
- ] as ExitTo[] )( 'should sync active document $ExitTo', ( exitTo ) => {
415
- // Arrange.
416
- const mockDocument = makeMockV1Document( { id: 1 } );
417
- mockV1DocumentsManager( [
418
- mockDocument,
419
- ], exitTo );
420
-
421
- // Populate the documents state.
422
- dispatchV1ReadyEvent();
423
-
424
- // Assert.
425
- const currentDocument = selectActiveDocument( store.getState() );
426
- const platformEdit = getV1DocumentsExitTo( mockDocument );
427
- const permalink = getV1DocumentPermalink( mockDocument );
428
-
429
- expect( currentDocument ).toEqual<Document>( {
430
- id: 1,
431
- title: 'Document 1',
432
- type: {
433
- value: 'wp-page',
434
- label: 'WP-PAGE',
435
- },
436
- links: {
437
- platformEdit,
438
- permalink,
439
- },
440
- status: {
441
- value: 'publish',
442
- label: 'PUBLISH',
443
- },
444
- isDirty: false,
445
- isSaving: false,
446
- isSavingDraft: false,
447
- userCan: {
448
- publish: true,
449
- },
450
- permissions: {
451
- allowAddingWidgets: true,
452
- showCopyAndShare: false,
453
- },
454
- } );
455
- } );
456
- } );
457
-
458
- function mockV1DocumentsManager( documentsArray: V1Document[], exitTo: ExitTo = 'this_post', current = 1, initial = 1 ) {
459
- ( window as unknown as WindowWithOptionalElementor ).elementor = {
460
- getPreferences: () => exitTo,
461
- documents: makeDocumentsManager( documentsArray, current, initial ),
462
- };
463
- }
@@ -1,106 +0,0 @@
1
- import { V1Document } from '../../types';
2
-
3
- export function dispatchCommandBefore( command: string, args: object = {} ) {
4
- window.dispatchEvent( new CustomEvent( 'elementor/commands/run/before', {
5
- detail: {
6
- command,
7
- args,
8
- },
9
- } ) );
10
- }
11
-
12
- export function dispatchCommandAfter( command: string, args: object = {} ) {
13
- window.dispatchEvent( new CustomEvent( 'elementor/commands/run/after', {
14
- detail: {
15
- command,
16
- args,
17
- },
18
- } ) );
19
- }
20
-
21
- export function dispatchWindowEvent( event: string ) {
22
- window.dispatchEvent( new CustomEvent( event ) );
23
- }
24
-
25
- export function dispatchV1ReadyEvent() {
26
- dispatchWindowEvent( 'elementor/initialized' );
27
- }
28
-
29
- export function makeDocumentsManager( documentsArray: V1Document[], current = 1, initial = current ) {
30
- const documents = documentsArray.reduce( ( acc: Record<number, V1Document>, document ) => {
31
- acc[ document.id ] = document;
32
-
33
- return acc;
34
- }, {} );
35
-
36
- return {
37
- documents,
38
- getCurrentId() {
39
- return current;
40
- },
41
- getInitialId() {
42
- return initial;
43
- },
44
- getCurrent() {
45
- return this.documents[ this.getCurrentId() ];
46
- },
47
- };
48
- }
49
-
50
- export function makeMockV1Document( {
51
- id = 1,
52
- title = 'Document ' + id,
53
- status = 'publish',
54
- type = 'wp-page',
55
- }: {
56
- id?: number,
57
- status?: string,
58
- title?: string,
59
- type?: string,
60
- } = {} ): V1Document {
61
- return {
62
- id,
63
- config: {
64
- type,
65
- user: {
66
- can_publish: true,
67
- },
68
- revisions: {
69
- current_id: id,
70
- },
71
- panel: {
72
- title: type.toUpperCase(),
73
- allow_adding_widgets: true,
74
- show_copy_and_share: false,
75
- },
76
- status: {
77
- label: status.toUpperCase(),
78
- value: status,
79
- },
80
- urls: {
81
- exit_to_dashboard: `https://localhost/wp-admin/post.php?post=${ id }&action=edit`,
82
- main_dashboard: `https://localhost/wp-admin/`,
83
- all_post_type: `https://localhost/wp-admin/post.php`,
84
- permalink: `https://localhost/?p=${ id }`,
85
- },
86
- },
87
- editor: {
88
- isChanged: false,
89
- isSaving: false,
90
- },
91
- container: {
92
- settings: makeV1Settings( {
93
- post_title: title,
94
- } ),
95
- },
96
- };
97
- }
98
-
99
- // Mock Backbone's settings model.
100
- function makeV1Settings<T extends object>( settings: T ) {
101
- return {
102
- get( key: keyof T ) {
103
- return settings[ key ];
104
- },
105
- } as V1Document['container']['settings'];
106
- }
@@ -1,19 +0,0 @@
1
- import { getV1DocumentsManager } from '../utils';
2
-
3
- /**
4
- * This test exists only because this function is being used only inside event handlers,
5
- * and jest can't catch errors that are being thrown. Despite that, we need to test this
6
- * specific behavior to make sure that we don't break the whole app when V1 isn't available.
7
- * All of the other logic is tested as an integration test in the `sync-store.test.ts` file,
8
- * while this one is a unit test.
9
- *
10
- * @see https://github.com/testing-library/react-testing-library/issues/624
11
- */
12
- describe( '@elementor/editor-documents - Sync Utils', () => {
13
- it( 'should throw when V1 documents manager is not available', () => {
14
- // Act & Assert.
15
- expect( () => {
16
- getV1DocumentsManager();
17
- } ).toThrow( 'Elementor Editor V1 documents manager not found' );
18
- } );
19
- } );