@elementor/editor-documents 0.11.5 → 0.11.7
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.
- package/CHANGELOG.md +10 -0
- package/package.json +13 -6
- package/src/hooks/__tests__/use-active-document-actions.test.ts +0 -52
- package/src/hooks/__tests__/use-active-document.test.tsx +0 -34
- package/src/hooks/__tests__/use-host-document.test.tsx +0 -49
- package/src/hooks/__tests__/use-navigate-to-document.test.ts +0 -60
- package/src/hooks/__tests__/use-sync-document-title.test.ts +0 -109
- package/src/sync/__tests__/sync-store.test.ts +0 -460
- package/src/sync/__tests__/test-utils.ts +0 -110
- package/src/sync/__tests__/utils.test.ts +0 -19
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.11.7](https://github.com/elementor/elementor-packages/compare/@elementor/editor-documents@0.11.6...@elementor/editor-documents@0.11.7) (2024-08-14)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @elementor/editor-documents
|
|
9
|
+
|
|
10
|
+
## [0.11.6](https://github.com/elementor/elementor-packages/compare/@elementor/editor-documents@0.11.5...@elementor/editor-documents@0.11.6) (2024-08-05)
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- publish only necessary files to npm ([#226](https://github.com/elementor/elementor-packages/issues/226)) ([d808e2f](https://github.com/elementor/elementor-packages/commit/d808e2f60eb7ca2d7b8560d0b79c0e62c2f969a8))
|
|
15
|
+
|
|
6
16
|
## [0.11.5](https://github.com/elementor/elementor-packages/compare/@elementor/editor-documents@0.11.4...@elementor/editor-documents@0.11.5) (2024-07-16)
|
|
7
17
|
|
|
8
18
|
**Note:** Version bump only for package @elementor/editor-documents
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-documents",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "https://github.com/elementor/elementor-packages.git",
|
|
21
|
+
"url": "git+https://github.com/elementor/elementor-packages.git",
|
|
22
22
|
"directory": "packages/core/editor-documents"
|
|
23
23
|
},
|
|
24
24
|
"bugs": {
|
|
@@ -27,18 +27,25 @@
|
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
|
+
"files": [
|
|
31
|
+
"README.md",
|
|
32
|
+
"CHANGELOG.md",
|
|
33
|
+
"/dist",
|
|
34
|
+
"/src",
|
|
35
|
+
"!**/__tests__"
|
|
36
|
+
],
|
|
30
37
|
"scripts": {
|
|
31
38
|
"build": "tsup --config=../../tsup.build.ts",
|
|
32
39
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
33
40
|
},
|
|
34
41
|
"dependencies": {
|
|
35
|
-
"@elementor/editor": "^0.
|
|
36
|
-
"@elementor/editor-v1-adapters": "^0.8.
|
|
37
|
-
"@elementor/store": "^0.8.
|
|
42
|
+
"@elementor/editor": "^0.13.0",
|
|
43
|
+
"@elementor/editor-v1-adapters": "^0.8.1",
|
|
44
|
+
"@elementor/store": "^0.8.5",
|
|
38
45
|
"@wordpress/i18n": "^4.45.0"
|
|
39
46
|
},
|
|
40
47
|
"peerDependencies": {
|
|
41
48
|
"react": "^18.3.1"
|
|
42
49
|
},
|
|
43
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "c42e605142983f0171e0f1fbcc902daa6ee00304"
|
|
44
51
|
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import useActiveDocumentActions from '../use-active-document-actions';
|
|
2
|
-
import { __privateOpenRoute as openRoute, __privateRunCommand as runCommand } from '@elementor/editor-v1-adapters';
|
|
3
|
-
import { __createStore, __registerSlice, SliceState, Store } from '@elementor/store';
|
|
4
|
-
import { slice } from '../../store';
|
|
5
|
-
import { renderHookWithStore } from 'test-utils';
|
|
6
|
-
|
|
7
|
-
jest.mock( '@elementor/editor-v1-adapters' );
|
|
8
|
-
|
|
9
|
-
describe( '@elementor/editor-documents - useActiveDocumentActions', () => {
|
|
10
|
-
let store: Store< SliceState< typeof slice > >;
|
|
11
|
-
|
|
12
|
-
beforeEach( () => {
|
|
13
|
-
__registerSlice( slice );
|
|
14
|
-
store = __createStore();
|
|
15
|
-
} );
|
|
16
|
-
|
|
17
|
-
it( 'should run documents actions', () => {
|
|
18
|
-
// Arrange.
|
|
19
|
-
const { result } = renderHookWithStore( useActiveDocumentActions, store );
|
|
20
|
-
|
|
21
|
-
const { save, saveDraft, saveTemplate } = result.current;
|
|
22
|
-
|
|
23
|
-
// Act.
|
|
24
|
-
save();
|
|
25
|
-
saveDraft();
|
|
26
|
-
saveTemplate();
|
|
27
|
-
|
|
28
|
-
// Assert.
|
|
29
|
-
expect( runCommand ).toHaveBeenCalledTimes( 2 );
|
|
30
|
-
|
|
31
|
-
expect( runCommand ).toHaveBeenNthCalledWith( 1, 'document/save/default' );
|
|
32
|
-
expect( runCommand ).toHaveBeenNthCalledWith( 2, 'document/save/draft' );
|
|
33
|
-
|
|
34
|
-
expect( openRoute ).toHaveBeenCalledTimes( 1 );
|
|
35
|
-
expect( openRoute ).toHaveBeenCalledWith( 'library/save-template' );
|
|
36
|
-
} );
|
|
37
|
-
|
|
38
|
-
it( 'should return memoized callbacks', () => {
|
|
39
|
-
// Arrange.
|
|
40
|
-
const { result, rerender } = renderHookWithStore( useActiveDocumentActions, store );
|
|
41
|
-
|
|
42
|
-
const { save, saveDraft, saveTemplate } = result.current;
|
|
43
|
-
|
|
44
|
-
// Act.
|
|
45
|
-
rerender();
|
|
46
|
-
|
|
47
|
-
// Assert.
|
|
48
|
-
expect( result.current.save ).toBe( save );
|
|
49
|
-
expect( result.current.saveDraft ).toBe( saveDraft );
|
|
50
|
-
expect( result.current.saveTemplate ).toBe( saveTemplate );
|
|
51
|
-
} );
|
|
52
|
-
} );
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { slice } from '../../store';
|
|
2
|
-
import useActiveDocument from '../use-active-document';
|
|
3
|
-
import { __createStore, __dispatch, __registerSlice, SliceState, Store } from '@elementor/store';
|
|
4
|
-
import { createMockDocument, renderHookWithStore } from 'test-utils';
|
|
5
|
-
|
|
6
|
-
describe( '@elementor/editor-documents - useActiveDocument', () => {
|
|
7
|
-
let store: Store< SliceState< typeof slice > >;
|
|
8
|
-
|
|
9
|
-
beforeEach( () => {
|
|
10
|
-
__registerSlice( slice );
|
|
11
|
-
store = __createStore();
|
|
12
|
-
} );
|
|
13
|
-
|
|
14
|
-
it( 'should return the current document', () => {
|
|
15
|
-
// Arrange.
|
|
16
|
-
const mockDocument = createMockDocument();
|
|
17
|
-
|
|
18
|
-
__dispatch( slice.actions.activateDocument( mockDocument ) );
|
|
19
|
-
|
|
20
|
-
// Act.
|
|
21
|
-
const { result } = renderHookWithStore( useActiveDocument, store );
|
|
22
|
-
|
|
23
|
-
// Assert.
|
|
24
|
-
expect( result.current ).toBe( mockDocument );
|
|
25
|
-
} );
|
|
26
|
-
|
|
27
|
-
it( 'should return null when the current document is not found', () => {
|
|
28
|
-
// Act.
|
|
29
|
-
const { result } = renderHookWithStore( useActiveDocument, store );
|
|
30
|
-
|
|
31
|
-
// Assert.
|
|
32
|
-
expect( result.current ).toBeNull();
|
|
33
|
-
} );
|
|
34
|
-
} );
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { slice } from '../../store';
|
|
2
|
-
import { __createStore, __dispatch, __registerSlice, SliceState, Store } from '@elementor/store';
|
|
3
|
-
import useHostDocument from '../use-host-document';
|
|
4
|
-
import { createMockDocument, renderHookWithStore } from 'test-utils';
|
|
5
|
-
|
|
6
|
-
describe( '@elementor/editor-documents - useHostDocument', () => {
|
|
7
|
-
const mockDocument = createMockDocument();
|
|
8
|
-
|
|
9
|
-
let store: Store< SliceState< typeof slice > >;
|
|
10
|
-
|
|
11
|
-
beforeEach( () => {
|
|
12
|
-
__registerSlice( slice );
|
|
13
|
-
store = __createStore();
|
|
14
|
-
} );
|
|
15
|
-
|
|
16
|
-
it( 'should return the host document', () => {
|
|
17
|
-
// Arrange.
|
|
18
|
-
__dispatch(
|
|
19
|
-
slice.actions.init( {
|
|
20
|
-
entities: { [ mockDocument.id ]: mockDocument },
|
|
21
|
-
activeId: null,
|
|
22
|
-
hostId: mockDocument.id,
|
|
23
|
-
} )
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
// Act.
|
|
27
|
-
const { result } = renderHookWithStore( useHostDocument, store );
|
|
28
|
-
|
|
29
|
-
// Assert.
|
|
30
|
-
expect( result.current ).toEqual( expect.objectContaining( { id: mockDocument.id } ) );
|
|
31
|
-
} );
|
|
32
|
-
|
|
33
|
-
it( 'should return null when the host document is not found', () => {
|
|
34
|
-
// Arrange.
|
|
35
|
-
__dispatch(
|
|
36
|
-
slice.actions.init( {
|
|
37
|
-
entities: { [ mockDocument.id ]: mockDocument },
|
|
38
|
-
activeId: null,
|
|
39
|
-
hostId: null,
|
|
40
|
-
} )
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
// Act.
|
|
44
|
-
const { result } = renderHookWithStore( useHostDocument, store );
|
|
45
|
-
|
|
46
|
-
// Assert.
|
|
47
|
-
expect( result.current ).toBeNull();
|
|
48
|
-
} );
|
|
49
|
-
} );
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { renderHook } from '@testing-library/react';
|
|
2
|
-
import { __privateRunCommand as runCommand } from '@elementor/editor-v1-adapters';
|
|
3
|
-
import { useNavigateToDocument } from '../index';
|
|
4
|
-
|
|
5
|
-
jest.mock( '@elementor/editor-v1-adapters' );
|
|
6
|
-
|
|
7
|
-
describe( '@elementor/editor-documents - useNavigateToDocument', () => {
|
|
8
|
-
const originalReplaceState = history.replaceState;
|
|
9
|
-
const originalLocation = window.location;
|
|
10
|
-
|
|
11
|
-
beforeEach( () => {
|
|
12
|
-
jest.resetAllMocks();
|
|
13
|
-
|
|
14
|
-
history.replaceState = jest.fn();
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @see https://gist.github.com/the0neWhoKnocks/bdac1d09b93b8418d948558f7ab233d7#setting-props-on-windowlocation
|
|
18
|
-
*/
|
|
19
|
-
Object.defineProperty( window, 'location', {
|
|
20
|
-
writable: true,
|
|
21
|
-
value: new URL( 'https://localhost/' ),
|
|
22
|
-
} );
|
|
23
|
-
} );
|
|
24
|
-
|
|
25
|
-
afterAll( () => {
|
|
26
|
-
history.replaceState = originalReplaceState;
|
|
27
|
-
|
|
28
|
-
Object.defineProperty( window, 'location', {
|
|
29
|
-
writable: false,
|
|
30
|
-
value: originalLocation,
|
|
31
|
-
} );
|
|
32
|
-
} );
|
|
33
|
-
|
|
34
|
-
it( 'should navigate to document and change query params', async () => {
|
|
35
|
-
// Arrange.
|
|
36
|
-
// TS doesn't allow modifying the location object.
|
|
37
|
-
( window as unknown as { location: URL } ).location = new URL( 'https://localhost/?post=1&active-document=3' );
|
|
38
|
-
|
|
39
|
-
const { result } = renderHook( useNavigateToDocument );
|
|
40
|
-
|
|
41
|
-
const navigateToDocument = result.current;
|
|
42
|
-
|
|
43
|
-
// Act.
|
|
44
|
-
await navigateToDocument( 123 );
|
|
45
|
-
|
|
46
|
-
// Assert.
|
|
47
|
-
expect( runCommand ).toHaveBeenCalledTimes( 1 );
|
|
48
|
-
expect( runCommand ).toHaveBeenCalledWith( 'editor/documents/switch', {
|
|
49
|
-
id: 123,
|
|
50
|
-
setAsInitial: true,
|
|
51
|
-
} );
|
|
52
|
-
|
|
53
|
-
expect( history.replaceState ).toHaveBeenCalledTimes( 1 );
|
|
54
|
-
expect( history.replaceState ).toHaveBeenCalledWith(
|
|
55
|
-
expect.anything(),
|
|
56
|
-
expect.anything(),
|
|
57
|
-
expect.objectContaining( { href: 'https://localhost/?post=123' } )
|
|
58
|
-
);
|
|
59
|
-
} );
|
|
60
|
-
} );
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { createMockDocument } from 'test-utils';
|
|
2
|
-
import { renderHook } from '@testing-library/react';
|
|
3
|
-
import useHostDocument from '../use-host-document';
|
|
4
|
-
import useActiveDocument from '../use-active-document';
|
|
5
|
-
import useSyncDocumentTitle from '../use-sync-document-title';
|
|
6
|
-
|
|
7
|
-
jest.mock( '../use-active-document' );
|
|
8
|
-
jest.mock( '../use-host-document' );
|
|
9
|
-
|
|
10
|
-
describe( 'useSyncDocumentTitle', () => {
|
|
11
|
-
beforeEach( () => {
|
|
12
|
-
jest.resetAllMocks();
|
|
13
|
-
} );
|
|
14
|
-
|
|
15
|
-
it( 'should set the document title to be the active document', () => {
|
|
16
|
-
// Arrange - set the initial document.
|
|
17
|
-
jest.mocked( useActiveDocument ).mockReturnValue(
|
|
18
|
-
createMockDocument( {
|
|
19
|
-
type: {
|
|
20
|
-
value: 'page',
|
|
21
|
-
label: 'Page',
|
|
22
|
-
},
|
|
23
|
-
title: 'Initial Document',
|
|
24
|
-
} )
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
// Act.
|
|
28
|
-
const { rerender } = renderHook( useSyncDocumentTitle );
|
|
29
|
-
|
|
30
|
-
// Assert.
|
|
31
|
-
expect( window.document.title ).toBe( 'Edit "Initial Document" with Elementor' );
|
|
32
|
-
|
|
33
|
-
// Arrange - set the new document.
|
|
34
|
-
jest.mocked( useActiveDocument ).mockReturnValue(
|
|
35
|
-
createMockDocument( {
|
|
36
|
-
type: {
|
|
37
|
-
value: 'page',
|
|
38
|
-
label: 'Page',
|
|
39
|
-
},
|
|
40
|
-
title: 'New Document',
|
|
41
|
-
} )
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
// Act.
|
|
45
|
-
rerender();
|
|
46
|
-
|
|
47
|
-
// Assert.
|
|
48
|
-
expect( window.document.title ).toBe( 'Edit "New Document" with Elementor' );
|
|
49
|
-
} );
|
|
50
|
-
|
|
51
|
-
it( 'should use the host document title when the active document is a kit', () => {
|
|
52
|
-
// Arrange.
|
|
53
|
-
jest.mocked( useActiveDocument ).mockReturnValue(
|
|
54
|
-
createMockDocument( {
|
|
55
|
-
type: {
|
|
56
|
-
value: 'kit',
|
|
57
|
-
label: 'Kit',
|
|
58
|
-
},
|
|
59
|
-
title: 'My Kit',
|
|
60
|
-
} )
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
jest.mocked( useHostDocument ).mockReturnValue(
|
|
64
|
-
createMockDocument( {
|
|
65
|
-
type: {
|
|
66
|
-
value: 'page',
|
|
67
|
-
label: 'Page',
|
|
68
|
-
},
|
|
69
|
-
title: 'My Page',
|
|
70
|
-
} )
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
window.document.title = 'Old title';
|
|
74
|
-
|
|
75
|
-
// Act.
|
|
76
|
-
renderHook( useSyncDocumentTitle );
|
|
77
|
-
|
|
78
|
-
// Assert.
|
|
79
|
-
expect( window.document.title ).toBe( 'Edit "My Page" with Elementor' );
|
|
80
|
-
} );
|
|
81
|
-
|
|
82
|
-
it( 'should not modify the title when there is no active document', () => {
|
|
83
|
-
// Arrange.
|
|
84
|
-
jest.mocked( useActiveDocument ).mockReturnValue( null );
|
|
85
|
-
|
|
86
|
-
window.document.title = 'Old title';
|
|
87
|
-
|
|
88
|
-
// Act.
|
|
89
|
-
renderHook( useSyncDocumentTitle );
|
|
90
|
-
|
|
91
|
-
// Assert.
|
|
92
|
-
expect( window.document.title ).toBe( 'Old title' );
|
|
93
|
-
} );
|
|
94
|
-
|
|
95
|
-
it( 'should allow empty string as title', () => {
|
|
96
|
-
// Arrange.
|
|
97
|
-
jest.mocked( useActiveDocument ).mockReturnValue(
|
|
98
|
-
createMockDocument( {
|
|
99
|
-
title: '',
|
|
100
|
-
} )
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
// Act.
|
|
104
|
-
renderHook( useSyncDocumentTitle );
|
|
105
|
-
|
|
106
|
-
// Assert.
|
|
107
|
-
expect( window.document.title ).toBe( 'Edit "" with Elementor' );
|
|
108
|
-
} );
|
|
109
|
-
} );
|
|
@@ -1,460 +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( [ makeMockV1Document( { id: 1 } ), makeMockV1Document( { id: 2 } ) ], 'this_post' );
|
|
38
|
-
|
|
39
|
-
// Act.
|
|
40
|
-
dispatchV1ReadyEvent();
|
|
41
|
-
|
|
42
|
-
// Assert.
|
|
43
|
-
const storeState = store.getState();
|
|
44
|
-
|
|
45
|
-
expect( storeState.documents.entities ).toEqual< Record< number, Document > >( {
|
|
46
|
-
1: {
|
|
47
|
-
id: 1,
|
|
48
|
-
title: 'Document 1',
|
|
49
|
-
type: {
|
|
50
|
-
value: 'wp-page',
|
|
51
|
-
label: 'WP-PAGE',
|
|
52
|
-
},
|
|
53
|
-
status: {
|
|
54
|
-
value: 'publish',
|
|
55
|
-
label: 'PUBLISH',
|
|
56
|
-
},
|
|
57
|
-
links: {
|
|
58
|
-
platformEdit: 'https://localhost/wp-admin/post.php?post=1&action=edit',
|
|
59
|
-
permalink: 'https://localhost/?p=1',
|
|
60
|
-
},
|
|
61
|
-
isDirty: false,
|
|
62
|
-
isSaving: false,
|
|
63
|
-
isSavingDraft: false,
|
|
64
|
-
userCan: {
|
|
65
|
-
publish: true,
|
|
66
|
-
},
|
|
67
|
-
permissions: {
|
|
68
|
-
allowAddingWidgets: true,
|
|
69
|
-
showCopyAndShare: false,
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
2: {
|
|
73
|
-
id: 2,
|
|
74
|
-
title: 'Document 2',
|
|
75
|
-
type: {
|
|
76
|
-
value: 'wp-page',
|
|
77
|
-
label: 'WP-PAGE',
|
|
78
|
-
},
|
|
79
|
-
status: {
|
|
80
|
-
value: 'publish',
|
|
81
|
-
label: 'PUBLISH',
|
|
82
|
-
},
|
|
83
|
-
links: {
|
|
84
|
-
platformEdit: 'https://localhost/wp-admin/post.php?post=2&action=edit',
|
|
85
|
-
permalink: 'https://localhost/?p=2',
|
|
86
|
-
},
|
|
87
|
-
isDirty: false,
|
|
88
|
-
isSaving: false,
|
|
89
|
-
isSavingDraft: false,
|
|
90
|
-
userCan: {
|
|
91
|
-
publish: true,
|
|
92
|
-
},
|
|
93
|
-
permissions: {
|
|
94
|
-
allowAddingWidgets: true,
|
|
95
|
-
showCopyAndShare: false,
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
} );
|
|
99
|
-
} );
|
|
100
|
-
|
|
101
|
-
it.each( [
|
|
102
|
-
{
|
|
103
|
-
type: 'V1 load',
|
|
104
|
-
dispatchEvent: () => dispatchV1ReadyEvent(),
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
type: 'document open',
|
|
108
|
-
dispatchEvent: () => dispatchCommandAfter( 'editor/documents/open' ),
|
|
109
|
-
},
|
|
110
|
-
] )( 'should sync active document on $type', ( { dispatchEvent } ) => {
|
|
111
|
-
// Arrange.
|
|
112
|
-
mockV1DocumentsManager( [ makeMockV1Document( { id: 1 } ), makeMockV1Document( { id: 2 } ) ], 'this_post', 2 );
|
|
113
|
-
|
|
114
|
-
// Act.
|
|
115
|
-
dispatchEvent();
|
|
116
|
-
|
|
117
|
-
// Assert.
|
|
118
|
-
const currentDocument = selectActiveDocument( store.getState() );
|
|
119
|
-
|
|
120
|
-
expect( currentDocument ).toEqual< Document >( {
|
|
121
|
-
id: 2,
|
|
122
|
-
title: 'Document 2',
|
|
123
|
-
type: {
|
|
124
|
-
value: 'wp-page',
|
|
125
|
-
label: 'WP-PAGE',
|
|
126
|
-
},
|
|
127
|
-
links: {
|
|
128
|
-
platformEdit: 'https://localhost/wp-admin/post.php?post=2&action=edit',
|
|
129
|
-
permalink: 'https://localhost/?p=2',
|
|
130
|
-
},
|
|
131
|
-
status: {
|
|
132
|
-
value: 'publish',
|
|
133
|
-
label: 'PUBLISH',
|
|
134
|
-
},
|
|
135
|
-
isDirty: false,
|
|
136
|
-
isSaving: false,
|
|
137
|
-
isSavingDraft: false,
|
|
138
|
-
userCan: {
|
|
139
|
-
publish: true,
|
|
140
|
-
},
|
|
141
|
-
permissions: {
|
|
142
|
-
allowAddingWidgets: true,
|
|
143
|
-
showCopyAndShare: false,
|
|
144
|
-
},
|
|
145
|
-
} );
|
|
146
|
-
} );
|
|
147
|
-
|
|
148
|
-
it.each( [
|
|
149
|
-
{
|
|
150
|
-
openAsHost: true,
|
|
151
|
-
expectedHost: 2,
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
openAsHost: false,
|
|
155
|
-
expectedHost: 1,
|
|
156
|
-
},
|
|
157
|
-
] )(
|
|
158
|
-
'should sync host document when a new host is opened { openAsHost: $openAsHost }',
|
|
159
|
-
( { openAsHost, expectedHost } ) => {
|
|
160
|
-
// Arrange.
|
|
161
|
-
const mockDocument1 = makeMockV1Document( { id: 1 } );
|
|
162
|
-
const mockDocument2 = makeMockV1Document( { id: 2 } );
|
|
163
|
-
|
|
164
|
-
mockV1DocumentsManager( [ mockDocument1, mockDocument2 ], 'this_post', 1, 1 );
|
|
165
|
-
|
|
166
|
-
// Populate the documents state.
|
|
167
|
-
dispatchV1ReadyEvent();
|
|
168
|
-
|
|
169
|
-
// Act - Mock a host document change.
|
|
170
|
-
mockV1DocumentsManager( [ mockDocument1, mockDocument2 ], 'this_post', 2, openAsHost ? 2 : 1 );
|
|
171
|
-
|
|
172
|
-
dispatchCommandAfter( 'editor/documents/open' );
|
|
173
|
-
|
|
174
|
-
// Assert.
|
|
175
|
-
expect( store.getState().documents.hostId ).toBe( expectedHost );
|
|
176
|
-
}
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
it( 'should sync saving state of a document on V1 load', () => {
|
|
180
|
-
// Arrange.
|
|
181
|
-
const mockDocument = makeMockV1Document();
|
|
182
|
-
|
|
183
|
-
mockV1DocumentsManager( [
|
|
184
|
-
{
|
|
185
|
-
...mockDocument,
|
|
186
|
-
editor: {
|
|
187
|
-
...mockDocument.editor,
|
|
188
|
-
isSaving: true,
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
] );
|
|
192
|
-
|
|
193
|
-
// Act.
|
|
194
|
-
dispatchV1ReadyEvent();
|
|
195
|
-
|
|
196
|
-
// Assert.
|
|
197
|
-
expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( true );
|
|
198
|
-
} );
|
|
199
|
-
|
|
200
|
-
it( 'should sync saving state of a document on save', () => {
|
|
201
|
-
// Arrange.
|
|
202
|
-
mockV1DocumentsManager( [ makeMockV1Document() ] );
|
|
203
|
-
|
|
204
|
-
// Populate the documents state.
|
|
205
|
-
dispatchV1ReadyEvent();
|
|
206
|
-
|
|
207
|
-
// Assert - Default state.
|
|
208
|
-
expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( false );
|
|
209
|
-
|
|
210
|
-
// Act.
|
|
211
|
-
dispatchCommandBefore( 'document/save/save' );
|
|
212
|
-
|
|
213
|
-
// Assert - On save start.
|
|
214
|
-
expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( true );
|
|
215
|
-
expect( selectActiveDocument( store.getState() )?.isSavingDraft ).toBe( false );
|
|
216
|
-
|
|
217
|
-
// Act.
|
|
218
|
-
dispatchCommandAfter( 'document/save/save' );
|
|
219
|
-
|
|
220
|
-
// Assert - On save end.
|
|
221
|
-
expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( false );
|
|
222
|
-
expect( selectActiveDocument( store.getState() )?.isSavingDraft ).toBe( false );
|
|
223
|
-
} );
|
|
224
|
-
|
|
225
|
-
it( 'should sync draft saving state of a document on save', () => {
|
|
226
|
-
// Arrange.
|
|
227
|
-
mockV1DocumentsManager( [ makeMockV1Document() ] );
|
|
228
|
-
|
|
229
|
-
// Populate the documents state.
|
|
230
|
-
dispatchV1ReadyEvent();
|
|
231
|
-
|
|
232
|
-
// Assert - Default state.
|
|
233
|
-
expect( selectActiveDocument( store.getState() )?.isSavingDraft ).toBe( false );
|
|
234
|
-
|
|
235
|
-
// Act.
|
|
236
|
-
dispatchCommandBefore( 'document/save/save', {
|
|
237
|
-
status: 'autosave',
|
|
238
|
-
} );
|
|
239
|
-
|
|
240
|
-
// Assert - On save start.
|
|
241
|
-
expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( false );
|
|
242
|
-
expect( selectActiveDocument( store.getState() )?.isSavingDraft ).toBe( true );
|
|
243
|
-
|
|
244
|
-
// Act.
|
|
245
|
-
dispatchCommandAfter( 'document/save/save', {
|
|
246
|
-
status: 'autosave',
|
|
247
|
-
} );
|
|
248
|
-
|
|
249
|
-
// Assert - On save end.
|
|
250
|
-
expect( selectActiveDocument( store.getState() )?.isSaving ).toBe( false );
|
|
251
|
-
expect( selectActiveDocument( store.getState() )?.isSavingDraft ).toBe( false );
|
|
252
|
-
} );
|
|
253
|
-
|
|
254
|
-
it( 'should sync dirty state of a document when it has an autosave', () => {
|
|
255
|
-
// Arrange.
|
|
256
|
-
const mockDocument = makeMockV1Document( { id: 1 } );
|
|
257
|
-
|
|
258
|
-
mockV1DocumentsManager( [
|
|
259
|
-
{
|
|
260
|
-
...mockDocument,
|
|
261
|
-
config: {
|
|
262
|
-
...mockDocument.config,
|
|
263
|
-
revisions: {
|
|
264
|
-
current_id: 2,
|
|
265
|
-
},
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
] );
|
|
269
|
-
|
|
270
|
-
// Act.
|
|
271
|
-
dispatchV1ReadyEvent();
|
|
272
|
-
|
|
273
|
-
// Assert.
|
|
274
|
-
expect( selectActiveDocument( store.getState() )?.isDirty ).toBe( true );
|
|
275
|
-
} );
|
|
276
|
-
|
|
277
|
-
it( 'should sync dirty state of a document on document change', () => {
|
|
278
|
-
// Arrange.
|
|
279
|
-
const mockDocument = makeMockV1Document();
|
|
280
|
-
|
|
281
|
-
mockV1DocumentsManager( [ mockDocument ] );
|
|
282
|
-
|
|
283
|
-
// Populate the documents state.
|
|
284
|
-
dispatchV1ReadyEvent();
|
|
285
|
-
|
|
286
|
-
// Mock a change.
|
|
287
|
-
mockDocument.editor.isChanged = true;
|
|
288
|
-
|
|
289
|
-
// Assert - Default state.
|
|
290
|
-
expect( selectActiveDocument( store.getState() )?.isDirty ).toBe( false );
|
|
291
|
-
|
|
292
|
-
// Act.
|
|
293
|
-
dispatchCommandAfter( 'document/save/set-is-modified' );
|
|
294
|
-
|
|
295
|
-
// Assert - After change.
|
|
296
|
-
expect( selectActiveDocument( store.getState() )?.isDirty ).toBe( true );
|
|
297
|
-
|
|
298
|
-
// Emulate a save / undo action that flips the `isChanged` back to `false`.
|
|
299
|
-
mockDocument.editor.isChanged = false;
|
|
300
|
-
|
|
301
|
-
dispatchCommandAfter( 'document/save/set-is-modified' );
|
|
302
|
-
|
|
303
|
-
// Assert - After change.
|
|
304
|
-
expect( selectActiveDocument( store.getState() )?.isDirty ).toBe( false );
|
|
305
|
-
} );
|
|
306
|
-
|
|
307
|
-
it( 'should sync document title on V1 setting change', () => {
|
|
308
|
-
// Arrange.
|
|
309
|
-
mockV1DocumentsManager( [
|
|
310
|
-
makeMockV1Document( {
|
|
311
|
-
title: 'old title',
|
|
312
|
-
} ),
|
|
313
|
-
] );
|
|
314
|
-
|
|
315
|
-
// Populate the documents state.
|
|
316
|
-
dispatchV1ReadyEvent();
|
|
317
|
-
|
|
318
|
-
// Act - simulate a change.
|
|
319
|
-
mockV1DocumentsManager( [
|
|
320
|
-
makeMockV1Document( {
|
|
321
|
-
title: 'new title',
|
|
322
|
-
} ),
|
|
323
|
-
] );
|
|
324
|
-
|
|
325
|
-
dispatchCommandAfter( 'document/elements/settings', {
|
|
326
|
-
settings: {
|
|
327
|
-
post_title: 'new title',
|
|
328
|
-
},
|
|
329
|
-
} );
|
|
330
|
-
|
|
331
|
-
jest.runAllTimers();
|
|
332
|
-
|
|
333
|
-
// Assert.
|
|
334
|
-
expect( selectActiveDocument( store.getState() )?.title ).toBe( 'new title' );
|
|
335
|
-
} );
|
|
336
|
-
|
|
337
|
-
it( 'should not sync document title when a non-related V1 setting has changed', () => {
|
|
338
|
-
// Arrange.
|
|
339
|
-
mockV1DocumentsManager( [
|
|
340
|
-
makeMockV1Document( {
|
|
341
|
-
title: 'old title',
|
|
342
|
-
} ),
|
|
343
|
-
] );
|
|
344
|
-
|
|
345
|
-
// Populate the documents state.
|
|
346
|
-
dispatchV1ReadyEvent();
|
|
347
|
-
|
|
348
|
-
// Act - simulate a change.
|
|
349
|
-
dispatchCommandAfter( 'document/elements/settings', {
|
|
350
|
-
settings: {
|
|
351
|
-
nonRelated: 'value',
|
|
352
|
-
},
|
|
353
|
-
} );
|
|
354
|
-
|
|
355
|
-
jest.runAllTimers();
|
|
356
|
-
|
|
357
|
-
// Assert.
|
|
358
|
-
expect( selectActiveDocument( store.getState() )?.title ).toBe( 'old title' );
|
|
359
|
-
} );
|
|
360
|
-
|
|
361
|
-
it( 'should update the document when finish saving', () => {
|
|
362
|
-
// Arrange.
|
|
363
|
-
mockV1DocumentsManager(
|
|
364
|
-
[
|
|
365
|
-
makeMockV1Document( {
|
|
366
|
-
id: 1,
|
|
367
|
-
status: 'draft',
|
|
368
|
-
title: 'test',
|
|
369
|
-
} ),
|
|
370
|
-
],
|
|
371
|
-
'this_post'
|
|
372
|
-
);
|
|
373
|
-
|
|
374
|
-
// Populate the documents state.
|
|
375
|
-
dispatchV1ReadyEvent();
|
|
376
|
-
|
|
377
|
-
// Mock a change.
|
|
378
|
-
mockV1DocumentsManager(
|
|
379
|
-
[
|
|
380
|
-
makeMockV1Document( {
|
|
381
|
-
id: 1,
|
|
382
|
-
status: 'publish',
|
|
383
|
-
title: 'test title changed',
|
|
384
|
-
} ),
|
|
385
|
-
],
|
|
386
|
-
'dashboard'
|
|
387
|
-
);
|
|
388
|
-
|
|
389
|
-
// Assert.
|
|
390
|
-
expect( selectActiveDocument( store.getState() )?.title ).toBe( 'test' );
|
|
391
|
-
expect( selectActiveDocument( store.getState() )?.status.value ).toBe( 'draft' );
|
|
392
|
-
expect( selectActiveDocument( store.getState() )?.links.platformEdit ).toBe(
|
|
393
|
-
'https://localhost/wp-admin/post.php?post=1&action=edit'
|
|
394
|
-
);
|
|
395
|
-
|
|
396
|
-
// Act.
|
|
397
|
-
dispatchCommandAfter( 'document/save/save' );
|
|
398
|
-
|
|
399
|
-
// Assert.
|
|
400
|
-
expect( selectActiveDocument( store.getState() )?.title ).toBe( 'test title changed' );
|
|
401
|
-
expect( selectActiveDocument( store.getState() )?.status.value ).toBe( 'publish' );
|
|
402
|
-
expect( selectActiveDocument( store.getState() )?.links.platformEdit ).toBe( 'https://localhost/wp-admin/' );
|
|
403
|
-
} );
|
|
404
|
-
|
|
405
|
-
it.each( [ 'dashboard', 'this_post', 'all_posts' ] as ExitTo[] )(
|
|
406
|
-
'should sync active document $ExitTo',
|
|
407
|
-
( exitTo ) => {
|
|
408
|
-
// Arrange.
|
|
409
|
-
const mockDocument = makeMockV1Document( { id: 1 } );
|
|
410
|
-
mockV1DocumentsManager( [ mockDocument ], exitTo );
|
|
411
|
-
|
|
412
|
-
// Populate the documents state.
|
|
413
|
-
dispatchV1ReadyEvent();
|
|
414
|
-
|
|
415
|
-
// Assert.
|
|
416
|
-
const currentDocument = selectActiveDocument( store.getState() );
|
|
417
|
-
const platformEdit = getV1DocumentsExitTo( mockDocument );
|
|
418
|
-
const permalink = getV1DocumentPermalink( mockDocument );
|
|
419
|
-
|
|
420
|
-
expect( currentDocument ).toEqual< Document >( {
|
|
421
|
-
id: 1,
|
|
422
|
-
title: 'Document 1',
|
|
423
|
-
type: {
|
|
424
|
-
value: 'wp-page',
|
|
425
|
-
label: 'WP-PAGE',
|
|
426
|
-
},
|
|
427
|
-
links: {
|
|
428
|
-
platformEdit,
|
|
429
|
-
permalink,
|
|
430
|
-
},
|
|
431
|
-
status: {
|
|
432
|
-
value: 'publish',
|
|
433
|
-
label: 'PUBLISH',
|
|
434
|
-
},
|
|
435
|
-
isDirty: false,
|
|
436
|
-
isSaving: false,
|
|
437
|
-
isSavingDraft: false,
|
|
438
|
-
userCan: {
|
|
439
|
-
publish: true,
|
|
440
|
-
},
|
|
441
|
-
permissions: {
|
|
442
|
-
allowAddingWidgets: true,
|
|
443
|
-
showCopyAndShare: false,
|
|
444
|
-
},
|
|
445
|
-
} );
|
|
446
|
-
}
|
|
447
|
-
);
|
|
448
|
-
} );
|
|
449
|
-
|
|
450
|
-
function mockV1DocumentsManager(
|
|
451
|
-
documentsArray: V1Document[],
|
|
452
|
-
exitTo: ExitTo = 'this_post',
|
|
453
|
-
current = 1,
|
|
454
|
-
initial = 1
|
|
455
|
-
) {
|
|
456
|
-
( window as unknown as WindowWithOptionalElementor ).elementor = {
|
|
457
|
-
getPreferences: () => exitTo,
|
|
458
|
-
documents: makeDocumentsManager( documentsArray, current, initial ),
|
|
459
|
-
};
|
|
460
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { V1Document } from '../../types';
|
|
2
|
-
|
|
3
|
-
export function dispatchCommandBefore( command: string, args: object = {} ) {
|
|
4
|
-
window.dispatchEvent(
|
|
5
|
-
new CustomEvent( 'elementor/commands/run/before', {
|
|
6
|
-
detail: {
|
|
7
|
-
command,
|
|
8
|
-
args,
|
|
9
|
-
},
|
|
10
|
-
} )
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function dispatchCommandAfter( command: string, args: object = {} ) {
|
|
15
|
-
window.dispatchEvent(
|
|
16
|
-
new CustomEvent( 'elementor/commands/run/after', {
|
|
17
|
-
detail: {
|
|
18
|
-
command,
|
|
19
|
-
args,
|
|
20
|
-
},
|
|
21
|
-
} )
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function dispatchWindowEvent( event: string ) {
|
|
26
|
-
window.dispatchEvent( new CustomEvent( event ) );
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function dispatchV1ReadyEvent() {
|
|
30
|
-
dispatchWindowEvent( 'elementor/initialized' );
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function makeDocumentsManager( documentsArray: V1Document[], current = 1, initial = current ) {
|
|
34
|
-
const documents = documentsArray.reduce( ( acc: Record< number, V1Document >, document ) => {
|
|
35
|
-
acc[ document.id ] = document;
|
|
36
|
-
|
|
37
|
-
return acc;
|
|
38
|
-
}, {} );
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
documents,
|
|
42
|
-
getCurrentId() {
|
|
43
|
-
return current;
|
|
44
|
-
},
|
|
45
|
-
getInitialId() {
|
|
46
|
-
return initial;
|
|
47
|
-
},
|
|
48
|
-
getCurrent() {
|
|
49
|
-
return this.documents[ this.getCurrentId() ];
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function makeMockV1Document( {
|
|
55
|
-
id = 1,
|
|
56
|
-
title = 'Document ' + id,
|
|
57
|
-
status = 'publish',
|
|
58
|
-
type = 'wp-page',
|
|
59
|
-
}: {
|
|
60
|
-
id?: number;
|
|
61
|
-
status?: string;
|
|
62
|
-
title?: string;
|
|
63
|
-
type?: string;
|
|
64
|
-
} = {} ): V1Document {
|
|
65
|
-
return {
|
|
66
|
-
id,
|
|
67
|
-
config: {
|
|
68
|
-
type,
|
|
69
|
-
user: {
|
|
70
|
-
can_publish: true,
|
|
71
|
-
},
|
|
72
|
-
revisions: {
|
|
73
|
-
current_id: id,
|
|
74
|
-
},
|
|
75
|
-
panel: {
|
|
76
|
-
title: type.toUpperCase(),
|
|
77
|
-
allow_adding_widgets: true,
|
|
78
|
-
show_copy_and_share: false,
|
|
79
|
-
},
|
|
80
|
-
status: {
|
|
81
|
-
label: status.toUpperCase(),
|
|
82
|
-
value: status,
|
|
83
|
-
},
|
|
84
|
-
urls: {
|
|
85
|
-
exit_to_dashboard: `https://localhost/wp-admin/post.php?post=${ id }&action=edit`,
|
|
86
|
-
main_dashboard: `https://localhost/wp-admin/`,
|
|
87
|
-
all_post_type: `https://localhost/wp-admin/post.php`,
|
|
88
|
-
permalink: `https://localhost/?p=${ id }`,
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
editor: {
|
|
92
|
-
isChanged: false,
|
|
93
|
-
isSaving: false,
|
|
94
|
-
},
|
|
95
|
-
container: {
|
|
96
|
-
settings: makeV1Settings( {
|
|
97
|
-
post_title: title,
|
|
98
|
-
} ),
|
|
99
|
-
},
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Mock Backbone's settings model.
|
|
104
|
-
function makeV1Settings< T extends object >( settings: T ) {
|
|
105
|
-
return {
|
|
106
|
-
get( key: keyof T ) {
|
|
107
|
-
return settings[ key ];
|
|
108
|
-
},
|
|
109
|
-
} as V1Document[ 'container' ][ 'settings' ];
|
|
110
|
-
}
|
|
@@ -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
|
-
} );
|