@wordpress/core-data 7.40.2-next.v.202602271551.0 → 7.40.2
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/README.md +0 -27
- package/build/actions.cjs +9 -26
- package/build/actions.cjs.map +2 -2
- package/build/awareness/post-editor-awareness.cjs +45 -6
- package/build/awareness/post-editor-awareness.cjs.map +2 -2
- package/build/awareness/types.cjs.map +1 -1
- package/build/entities.cjs +36 -16
- package/build/entities.cjs.map +2 -2
- package/build/entity-provider.cjs +15 -6
- package/build/entity-provider.cjs.map +2 -2
- package/build/hooks/use-entity-prop.cjs +33 -2
- package/build/hooks/use-entity-prop.cjs.map +2 -2
- package/build/hooks/use-post-editor-awareness-state.cjs +120 -1
- package/build/hooks/use-post-editor-awareness-state.cjs.map +2 -2
- package/build/index.cjs +0 -3
- package/build/index.cjs.map +2 -2
- package/build/private-actions.cjs +27 -3
- package/build/private-actions.cjs.map +2 -2
- package/build/private-apis.cjs +14 -5
- package/build/private-apis.cjs.map +3 -3
- package/build/private-selectors.cjs +22 -2
- package/build/private-selectors.cjs.map +2 -2
- package/build/queried-data/actions.cjs +1 -1
- package/build/queried-data/actions.cjs.map +2 -2
- package/build/queried-data/reducer.cjs +19 -13
- package/build/queried-data/reducer.cjs.map +2 -2
- package/build/reducer.cjs +19 -2
- package/build/reducer.cjs.map +2 -2
- package/build/resolvers.cjs +24 -17
- package/build/resolvers.cjs.map +2 -2
- package/build/selectors.cjs +0 -15
- package/build/selectors.cjs.map +2 -2
- package/build/sync.cjs +12 -3
- package/build/sync.cjs.map +2 -2
- package/build/types.cjs.map +1 -1
- package/build/utils/block-selection-history.cjs +1 -1
- package/build/utils/block-selection-history.cjs.map +2 -2
- package/build/utils/crdt-blocks.cjs +85 -28
- package/build/utils/crdt-blocks.cjs.map +2 -2
- package/build/utils/crdt-selection.cjs +4 -1
- package/build/utils/crdt-selection.cjs.map +2 -2
- package/build/utils/crdt-text.cjs +52 -0
- package/build/utils/crdt-text.cjs.map +7 -0
- package/build/utils/crdt-user-selections.cjs +16 -6
- package/build/utils/crdt-user-selections.cjs.map +3 -3
- package/build/utils/crdt-utils.cjs +54 -2
- package/build/utils/crdt-utils.cjs.map +2 -2
- package/build/utils/crdt.cjs +26 -28
- package/build/utils/crdt.cjs.map +2 -2
- package/build-module/actions.mjs +14 -26
- package/build-module/actions.mjs.map +2 -2
- package/build-module/awareness/post-editor-awareness.mjs +47 -7
- package/build-module/awareness/post-editor-awareness.mjs.map +2 -2
- package/build-module/entities.mjs +37 -16
- package/build-module/entities.mjs.map +2 -2
- package/build-module/entity-provider.mjs +15 -6
- package/build-module/entity-provider.mjs.map +2 -2
- package/build-module/hooks/use-entity-prop.mjs +34 -3
- package/build-module/hooks/use-entity-prop.mjs.map +2 -2
- package/build-module/hooks/use-post-editor-awareness-state.mjs +117 -1
- package/build-module/hooks/use-post-editor-awareness-state.mjs.map +2 -2
- package/build-module/index.mjs +0 -2
- package/build-module/index.mjs.map +2 -2
- package/build-module/private-actions.mjs +24 -2
- package/build-module/private-actions.mjs.map +2 -2
- package/build-module/private-apis.mjs +21 -6
- package/build-module/private-apis.mjs.map +3 -3
- package/build-module/private-selectors.mjs +19 -1
- package/build-module/private-selectors.mjs.map +2 -2
- package/build-module/queried-data/actions.mjs +1 -1
- package/build-module/queried-data/actions.mjs.map +2 -2
- package/build-module/queried-data/reducer.mjs +19 -13
- package/build-module/queried-data/reducer.mjs.map +2 -2
- package/build-module/reducer.mjs +18 -2
- package/build-module/reducer.mjs.map +2 -2
- package/build-module/resolvers.mjs +24 -17
- package/build-module/resolvers.mjs.map +2 -2
- package/build-module/selectors.mjs +0 -14
- package/build-module/selectors.mjs.map +2 -2
- package/build-module/sync.mjs +8 -2
- package/build-module/sync.mjs.map +2 -2
- package/build-module/utils/block-selection-history.mjs +5 -2
- package/build-module/utils/block-selection-history.mjs.map +2 -2
- package/build-module/utils/crdt-blocks.mjs +84 -28
- package/build-module/utils/crdt-blocks.mjs.map +2 -2
- package/build-module/utils/crdt-selection.mjs +8 -2
- package/build-module/utils/crdt-selection.mjs.map +2 -2
- package/build-module/utils/crdt-text.mjs +26 -0
- package/build-module/utils/crdt-text.mjs.map +7 -0
- package/build-module/utils/crdt-user-selections.mjs +16 -7
- package/build-module/utils/crdt-user-selections.mjs.map +3 -3
- package/build-module/utils/crdt-utils.mjs +51 -1
- package/build-module/utils/crdt-utils.mjs.map +2 -2
- package/build-module/utils/crdt.mjs +26 -28
- package/build-module/utils/crdt.mjs.map +2 -2
- package/build-types/actions.d.ts +0 -11
- package/build-types/actions.d.ts.map +1 -1
- package/build-types/awareness/post-editor-awareness.d.ts +2 -2
- package/build-types/awareness/post-editor-awareness.d.ts.map +1 -1
- package/build-types/awareness/types.d.ts +6 -1
- package/build-types/awareness/types.d.ts.map +1 -1
- package/build-types/entities.d.ts +20 -1
- package/build-types/entities.d.ts.map +1 -1
- package/build-types/entity-provider.d.ts +11 -6
- package/build-types/entity-provider.d.ts.map +1 -1
- package/build-types/hooks/use-entity-prop.d.ts.map +1 -1
- package/build-types/hooks/use-post-editor-awareness-state.d.ts +40 -7
- package/build-types/hooks/use-post-editor-awareness-state.d.ts.map +1 -1
- package/build-types/index.d.ts +0 -3
- package/build-types/index.d.ts.map +1 -1
- package/build-types/parsed-blocks-cache.d.ts +10 -0
- package/build-types/parsed-blocks-cache.d.ts.map +1 -0
- package/build-types/private-actions.d.ts +12 -0
- package/build-types/private-actions.d.ts.map +1 -1
- package/build-types/private-apis.d.ts +21 -1
- package/build-types/private-apis.d.ts.map +1 -1
- package/build-types/private-selectors.d.ts +17 -0
- package/build-types/private-selectors.d.ts.map +1 -1
- package/build-types/queried-data/reducer.d.ts.map +1 -1
- package/build-types/reducer.d.ts +15 -0
- package/build-types/reducer.d.ts.map +1 -1
- package/build-types/resolvers.d.ts.map +1 -1
- package/build-types/selectors.d.ts +1 -9
- package/build-types/selectors.d.ts.map +1 -1
- package/build-types/sync.d.ts +2 -2
- package/build-types/sync.d.ts.map +1 -1
- package/build-types/types.d.ts +10 -2
- package/build-types/types.d.ts.map +1 -1
- package/build-types/utils/block-selection-history.d.ts.map +1 -1
- package/build-types/utils/crdt-blocks.d.ts +11 -0
- package/build-types/utils/crdt-blocks.d.ts.map +1 -1
- package/build-types/utils/crdt-selection.d.ts.map +1 -1
- package/build-types/utils/crdt-text.d.ts +16 -0
- package/build-types/utils/crdt-text.d.ts.map +1 -0
- package/build-types/utils/crdt-user-selections.d.ts +17 -4
- package/build-types/utils/crdt-user-selections.d.ts.map +1 -1
- package/build-types/utils/crdt-utils.d.ts +20 -0
- package/build-types/utils/crdt-utils.d.ts.map +1 -1
- package/build-types/utils/crdt.d.ts +13 -7
- package/build-types/utils/crdt.d.ts.map +1 -1
- package/build-types/utils/normalize-query-for-resolution.d.ts +12 -0
- package/build-types/utils/normalize-query-for-resolution.d.ts.map +1 -0
- package/build-types/utils/save-crdt-doc.d.ts +8 -0
- package/build-types/utils/save-crdt-doc.d.ts.map +1 -0
- package/build-types/utils/test/crdt-utils.d.ts +2 -0
- package/build-types/utils/test/crdt-utils.d.ts.map +1 -0
- package/package.json +18 -18
- package/src/actions.js +26 -41
- package/src/awareness/post-editor-awareness.ts +106 -7
- package/src/awareness/test/post-editor-awareness.ts +50 -10
- package/src/awareness/types.ts +7 -1
- package/src/entities.js +43 -17
- package/src/entity-provider.js +24 -11
- package/src/hooks/test/use-post-editor-awareness-state.ts +446 -3
- package/src/hooks/use-entity-prop.js +43 -3
- package/src/hooks/use-post-editor-awareness-state.ts +229 -7
- package/src/index.js +0 -6
- package/src/private-actions.js +43 -1
- package/src/{private-apis.js → private-apis.ts} +21 -3
- package/src/private-selectors.ts +43 -0
- package/src/queried-data/actions.js +1 -1
- package/src/queried-data/reducer.js +26 -14
- package/src/reducer.js +36 -1
- package/src/resolvers.js +33 -23
- package/src/selectors.ts +1 -32
- package/src/sync.ts +6 -0
- package/src/test/entities.js +204 -16
- package/src/test/private-actions.js +1 -1
- package/src/test/resolvers.js +144 -57
- package/src/test/store.js +116 -0
- package/src/types.ts +20 -2
- package/src/utils/block-selection-history.ts +5 -2
- package/src/utils/crdt-blocks.ts +159 -56
- package/src/utils/crdt-selection.ts +8 -2
- package/src/utils/crdt-text.ts +43 -0
- package/src/utils/crdt-user-selections.ts +29 -8
- package/src/utils/crdt-utils.ts +99 -0
- package/src/utils/crdt.ts +50 -40
- package/src/utils/test/crdt-blocks.ts +588 -24
- package/src/utils/test/crdt-user-selections.ts +5 -0
- package/src/utils/test/crdt-utils.ts +387 -0
- package/src/utils/test/crdt.ts +291 -54
package/src/sync.ts
CHANGED
|
@@ -12,18 +12,24 @@ import {
|
|
|
12
12
|
import { unlock } from './lock-unlock';
|
|
13
13
|
|
|
14
14
|
const {
|
|
15
|
+
ConnectionErrorCode,
|
|
15
16
|
createSyncManager,
|
|
16
17
|
Delta,
|
|
17
18
|
CRDT_DOC_META_PERSISTENCE_KEY,
|
|
18
19
|
CRDT_RECORD_MAP_KEY,
|
|
19
20
|
LOCAL_EDITOR_ORIGIN,
|
|
21
|
+
LOCAL_UNDO_IGNORED_ORIGIN,
|
|
22
|
+
retrySyncConnection,
|
|
20
23
|
} = unlock( syncPrivateApis );
|
|
21
24
|
|
|
22
25
|
export {
|
|
26
|
+
ConnectionErrorCode,
|
|
23
27
|
Delta,
|
|
24
28
|
CRDT_DOC_META_PERSISTENCE_KEY,
|
|
25
29
|
CRDT_RECORD_MAP_KEY,
|
|
26
30
|
LOCAL_EDITOR_ORIGIN,
|
|
31
|
+
LOCAL_UNDO_IGNORED_ORIGIN,
|
|
32
|
+
retrySyncConnection,
|
|
27
33
|
};
|
|
28
34
|
|
|
29
35
|
let syncManager: SyncManager;
|
package/src/test/entities.js
CHANGED
|
@@ -8,6 +8,10 @@ jest.mock( '../sync', () => ( {
|
|
|
8
8
|
...jest.requireActual( '../sync' ),
|
|
9
9
|
getSyncManager: jest.fn(),
|
|
10
10
|
} ) );
|
|
11
|
+
jest.mock( '../utils/crdt', () => ( {
|
|
12
|
+
...jest.requireActual( '../utils/crdt' ),
|
|
13
|
+
applyPostChangesToCRDTDoc: jest.fn(),
|
|
14
|
+
} ) );
|
|
11
15
|
|
|
12
16
|
/**
|
|
13
17
|
* Internal dependencies
|
|
@@ -19,7 +23,10 @@ import {
|
|
|
19
23
|
additionalEntityConfigLoaders,
|
|
20
24
|
} from '../entities';
|
|
21
25
|
import { getSyncManager } from '../sync';
|
|
22
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
applyPostChangesToCRDTDoc,
|
|
28
|
+
POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE,
|
|
29
|
+
} from '../utils/crdt';
|
|
23
30
|
|
|
24
31
|
describe( 'getMethodName', () => {
|
|
25
32
|
it( 'should return the right method name for an entity with the root kind', () => {
|
|
@@ -51,12 +58,14 @@ describe( 'getMethodName', () => {
|
|
|
51
58
|
} );
|
|
52
59
|
|
|
53
60
|
describe( 'prePersistPostType', () => {
|
|
54
|
-
it( 'set the status to draft and empty the title when saving auto-draft posts', () => {
|
|
61
|
+
it( 'set the status to draft and empty the title when saving auto-draft posts', async () => {
|
|
55
62
|
let record = {
|
|
56
63
|
status: 'auto-draft',
|
|
57
64
|
};
|
|
58
65
|
const edits = {};
|
|
59
|
-
expect(
|
|
66
|
+
expect(
|
|
67
|
+
await prePersistPostType( record, edits, 'post', false )
|
|
68
|
+
).toEqual( {
|
|
60
69
|
status: 'draft',
|
|
61
70
|
title: '',
|
|
62
71
|
} );
|
|
@@ -64,15 +73,17 @@ describe( 'prePersistPostType', () => {
|
|
|
64
73
|
record = {
|
|
65
74
|
status: 'publish',
|
|
66
75
|
};
|
|
67
|
-
expect(
|
|
68
|
-
|
|
69
|
-
);
|
|
76
|
+
expect(
|
|
77
|
+
await prePersistPostType( record, edits, 'post', false )
|
|
78
|
+
).toEqual( {} );
|
|
70
79
|
|
|
71
80
|
record = {
|
|
72
81
|
status: 'auto-draft',
|
|
73
82
|
title: 'Auto Draft',
|
|
74
83
|
};
|
|
75
|
-
expect(
|
|
84
|
+
expect(
|
|
85
|
+
await prePersistPostType( record, edits, 'post', false )
|
|
86
|
+
).toEqual( {
|
|
76
87
|
status: 'draft',
|
|
77
88
|
title: '',
|
|
78
89
|
} );
|
|
@@ -81,23 +92,23 @@ describe( 'prePersistPostType', () => {
|
|
|
81
92
|
status: 'publish',
|
|
82
93
|
title: 'My Title',
|
|
83
94
|
};
|
|
84
|
-
expect(
|
|
85
|
-
|
|
86
|
-
);
|
|
95
|
+
expect(
|
|
96
|
+
await prePersistPostType( record, edits, 'post', false )
|
|
97
|
+
).toEqual( {} );
|
|
87
98
|
} );
|
|
88
99
|
|
|
89
|
-
it( 'does not set the status to draft and empty the title when saving templates', () => {
|
|
100
|
+
it( 'does not set the status to draft and empty the title when saving templates', async () => {
|
|
90
101
|
const record = {
|
|
91
102
|
status: 'auto-draft',
|
|
92
103
|
title: 'Auto Draft',
|
|
93
104
|
};
|
|
94
105
|
const edits = {};
|
|
95
|
-
expect(
|
|
96
|
-
|
|
97
|
-
);
|
|
106
|
+
expect(
|
|
107
|
+
await prePersistPostType( record, edits, 'post', true )
|
|
108
|
+
).toEqual( {} );
|
|
98
109
|
} );
|
|
99
110
|
|
|
100
|
-
it( 'adds meta with serialized CRDT doc when createPersistedCRDTDoc returns a value', () => {
|
|
111
|
+
it( 'adds meta with serialized CRDT doc when createPersistedCRDTDoc returns a value', async () => {
|
|
101
112
|
const mockSerializedDoc = 'serialized-crdt-doc-data';
|
|
102
113
|
getSyncManager.mockReturnValue( {
|
|
103
114
|
createPersistedCRDTDoc: jest
|
|
@@ -107,7 +118,7 @@ describe( 'prePersistPostType', () => {
|
|
|
107
118
|
|
|
108
119
|
const record = { id: 123, status: 'publish' };
|
|
109
120
|
const edits = {};
|
|
110
|
-
const result = prePersistPostType( record, edits, 'post', false );
|
|
121
|
+
const result = await prePersistPostType( record, edits, 'post', false );
|
|
111
122
|
|
|
112
123
|
expect( result.meta ).toEqual( {
|
|
113
124
|
[ POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE ]: mockSerializedDoc,
|
|
@@ -123,6 +134,183 @@ describe( 'prePersistPostType', () => {
|
|
|
123
134
|
} );
|
|
124
135
|
} );
|
|
125
136
|
|
|
137
|
+
describe( 'loadPostTypeEntities', () => {
|
|
138
|
+
let originalCollaborationEnabled;
|
|
139
|
+
|
|
140
|
+
beforeEach( () => {
|
|
141
|
+
apiFetch.mockReset();
|
|
142
|
+
applyPostChangesToCRDTDoc.mockReset();
|
|
143
|
+
originalCollaborationEnabled = window._wpCollaborationEnabled;
|
|
144
|
+
} );
|
|
145
|
+
|
|
146
|
+
afterEach( () => {
|
|
147
|
+
window._wpCollaborationEnabled = originalCollaborationEnabled;
|
|
148
|
+
} );
|
|
149
|
+
|
|
150
|
+
it( 'should include custom taxonomy rest_bases in synced properties when collaboration is enabled', async () => {
|
|
151
|
+
window._wpCollaborationEnabled = true;
|
|
152
|
+
|
|
153
|
+
const mockPostTypes = {
|
|
154
|
+
book: {
|
|
155
|
+
name: 'Books',
|
|
156
|
+
rest_base: 'books',
|
|
157
|
+
rest_namespace: 'wp/v2',
|
|
158
|
+
taxonomies: [ 'genre', 'audience' ],
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
const mockTaxonomies = {
|
|
162
|
+
genre: {
|
|
163
|
+
name: 'Genres',
|
|
164
|
+
rest_base: 'genres',
|
|
165
|
+
rest_namespace: 'wp/v2',
|
|
166
|
+
},
|
|
167
|
+
audience: {
|
|
168
|
+
name: 'Audiences',
|
|
169
|
+
rest_base: 'audiences',
|
|
170
|
+
rest_namespace: 'wp/v2',
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
apiFetch
|
|
175
|
+
.mockResolvedValueOnce( mockPostTypes )
|
|
176
|
+
.mockResolvedValueOnce( mockTaxonomies );
|
|
177
|
+
|
|
178
|
+
const postTypeLoader = additionalEntityConfigLoaders.find(
|
|
179
|
+
( loader ) => loader.kind === 'postType'
|
|
180
|
+
);
|
|
181
|
+
const entities = await postTypeLoader.loadEntities();
|
|
182
|
+
const bookEntity = entities.find( ( e ) => e.name === 'book' );
|
|
183
|
+
|
|
184
|
+
bookEntity.syncConfig.applyChangesToCRDTDoc( {}, {} );
|
|
185
|
+
|
|
186
|
+
expect( applyPostChangesToCRDTDoc ).toHaveBeenCalledWith(
|
|
187
|
+
{},
|
|
188
|
+
{},
|
|
189
|
+
expect.any( Set )
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
const syncedProperties = applyPostChangesToCRDTDoc.mock.calls[ 0 ][ 2 ];
|
|
193
|
+
expect( syncedProperties ).toContain( 'genres' );
|
|
194
|
+
expect( syncedProperties ).toContain( 'audiences' );
|
|
195
|
+
} );
|
|
196
|
+
|
|
197
|
+
it( 'should not fetch taxonomies when collaboration is disabled', async () => {
|
|
198
|
+
window._wpCollaborationEnabled = false;
|
|
199
|
+
|
|
200
|
+
const mockPostTypes = {
|
|
201
|
+
post: {
|
|
202
|
+
name: 'Posts',
|
|
203
|
+
rest_base: 'posts',
|
|
204
|
+
rest_namespace: 'wp/v2',
|
|
205
|
+
taxonomies: [ 'category', 'post_tag' ],
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
apiFetch.mockResolvedValueOnce( mockPostTypes );
|
|
210
|
+
|
|
211
|
+
const postTypeLoader = additionalEntityConfigLoaders.find(
|
|
212
|
+
( loader ) => loader.kind === 'postType'
|
|
213
|
+
);
|
|
214
|
+
const entities = await postTypeLoader.loadEntities();
|
|
215
|
+
const postEntity = entities.find( ( e ) => e.name === 'post' );
|
|
216
|
+
|
|
217
|
+
postEntity.syncConfig.applyChangesToCRDTDoc( {}, {} );
|
|
218
|
+
|
|
219
|
+
// Only one apiFetch call (post types), no taxonomy fetch.
|
|
220
|
+
expect( apiFetch ).toHaveBeenCalledTimes( 1 );
|
|
221
|
+
|
|
222
|
+
const syncedProperties = applyPostChangesToCRDTDoc.mock.calls[ 0 ][ 2 ];
|
|
223
|
+
expect( syncedProperties ).not.toContain( 'categories' );
|
|
224
|
+
expect( syncedProperties ).not.toContain( 'tags' );
|
|
225
|
+
} );
|
|
226
|
+
|
|
227
|
+
it( 'should skip taxonomy rest_base when taxonomy is not found in fetched taxonomies', async () => {
|
|
228
|
+
window._wpCollaborationEnabled = true;
|
|
229
|
+
|
|
230
|
+
const mockPostTypes = {
|
|
231
|
+
book: {
|
|
232
|
+
name: 'Books',
|
|
233
|
+
rest_base: 'books',
|
|
234
|
+
rest_namespace: 'wp/v2',
|
|
235
|
+
taxonomies: [ 'genre', 'missing_taxonomy' ],
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
const mockTaxonomies = {
|
|
239
|
+
genre: {
|
|
240
|
+
name: 'Genres',
|
|
241
|
+
rest_base: 'genres',
|
|
242
|
+
rest_namespace: 'wp/v2',
|
|
243
|
+
},
|
|
244
|
+
// 'missing_taxonomy' is intentionally absent.
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
apiFetch
|
|
248
|
+
.mockResolvedValueOnce( mockPostTypes )
|
|
249
|
+
.mockResolvedValueOnce( mockTaxonomies );
|
|
250
|
+
|
|
251
|
+
const postTypeLoader = additionalEntityConfigLoaders.find(
|
|
252
|
+
( loader ) => loader.kind === 'postType'
|
|
253
|
+
);
|
|
254
|
+
const entities = await postTypeLoader.loadEntities();
|
|
255
|
+
const bookEntity = entities.find( ( e ) => e.name === 'book' );
|
|
256
|
+
|
|
257
|
+
bookEntity.syncConfig.applyChangesToCRDTDoc( {}, {} );
|
|
258
|
+
|
|
259
|
+
const syncedProperties = applyPostChangesToCRDTDoc.mock.calls[ 0 ][ 2 ];
|
|
260
|
+
expect( syncedProperties ).toContain( 'genres' );
|
|
261
|
+
// missing_taxonomy has no rest_base entry, so nothing should be added for it.
|
|
262
|
+
expect( syncedProperties.size ).toBe( 16 ); // 15 base + 1 taxonomy (genres)
|
|
263
|
+
} );
|
|
264
|
+
|
|
265
|
+
it( 'should include base synced properties regardless of taxonomies', async () => {
|
|
266
|
+
window._wpCollaborationEnabled = true;
|
|
267
|
+
|
|
268
|
+
const mockPostTypes = {
|
|
269
|
+
page: {
|
|
270
|
+
name: 'Pages',
|
|
271
|
+
rest_base: 'pages',
|
|
272
|
+
rest_namespace: 'wp/v2',
|
|
273
|
+
taxonomies: [],
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
apiFetch
|
|
278
|
+
.mockResolvedValueOnce( mockPostTypes )
|
|
279
|
+
.mockResolvedValueOnce( {} );
|
|
280
|
+
|
|
281
|
+
const postTypeLoader = additionalEntityConfigLoaders.find(
|
|
282
|
+
( loader ) => loader.kind === 'postType'
|
|
283
|
+
);
|
|
284
|
+
const entities = await postTypeLoader.loadEntities();
|
|
285
|
+
const pageEntity = entities.find( ( e ) => e.name === 'page' );
|
|
286
|
+
|
|
287
|
+
pageEntity.syncConfig.applyChangesToCRDTDoc( {}, {} );
|
|
288
|
+
|
|
289
|
+
const syncedProperties = applyPostChangesToCRDTDoc.mock.calls[ 0 ][ 2 ];
|
|
290
|
+
const expectedBase = [
|
|
291
|
+
'author',
|
|
292
|
+
'blocks',
|
|
293
|
+
'content',
|
|
294
|
+
'comment_status',
|
|
295
|
+
'date',
|
|
296
|
+
'excerpt',
|
|
297
|
+
'featured_media',
|
|
298
|
+
'format',
|
|
299
|
+
'meta',
|
|
300
|
+
'ping_status',
|
|
301
|
+
'slug',
|
|
302
|
+
'status',
|
|
303
|
+
'sticky',
|
|
304
|
+
'template',
|
|
305
|
+
'title',
|
|
306
|
+
];
|
|
307
|
+
for ( const prop of expectedBase ) {
|
|
308
|
+
expect( syncedProperties ).toContain( prop );
|
|
309
|
+
}
|
|
310
|
+
expect( syncedProperties.size ).toBe( 15 );
|
|
311
|
+
} );
|
|
312
|
+
} );
|
|
313
|
+
|
|
126
314
|
describe( 'loadTaxonomyEntities', () => {
|
|
127
315
|
beforeEach( () => {
|
|
128
316
|
apiFetch.mockReset();
|
package/src/test/resolvers.js
CHANGED
|
@@ -172,16 +172,69 @@ describe( 'getEntityRecord', () => {
|
|
|
172
172
|
editRecord: expect.any( Function ),
|
|
173
173
|
getEditedRecord: expect.any( Function ),
|
|
174
174
|
onStatusChange: expect.any( Function ),
|
|
175
|
+
persistCRDTDoc: expect.any( Function ),
|
|
175
176
|
refetchRecord: expect.any( Function ),
|
|
176
177
|
restoreUndoMeta: expect.any( Function ),
|
|
177
|
-
saveRecord: expect.any( Function ),
|
|
178
178
|
}
|
|
179
179
|
);
|
|
180
180
|
} );
|
|
181
181
|
|
|
182
|
-
it( '
|
|
183
|
-
const
|
|
184
|
-
const EDITED_RECORD = { id: 1, title: 'Edited
|
|
182
|
+
it( 'persistCRDTDoc fetches edited record and does not save full entity record when the entity does not support meta', async () => {
|
|
183
|
+
const ENTITY_RECORD = { id: 1, title: 'Test Record' };
|
|
184
|
+
const EDITED_RECORD = { id: 1, title: 'Edited Record' };
|
|
185
|
+
const ENTITY_RESPONSE = {
|
|
186
|
+
json: () => Promise.resolve( ENTITY_RECORD ),
|
|
187
|
+
};
|
|
188
|
+
const ENTITIES_WITH_SYNC = [
|
|
189
|
+
{
|
|
190
|
+
name: 'bar',
|
|
191
|
+
kind: 'foo',
|
|
192
|
+
baseURL: '/wp/v2/foo',
|
|
193
|
+
baseURLParams: { context: 'edit' },
|
|
194
|
+
syncConfig: {},
|
|
195
|
+
},
|
|
196
|
+
];
|
|
197
|
+
|
|
198
|
+
dispatch.saveEntityRecord = jest.fn();
|
|
199
|
+
|
|
200
|
+
const resolveSelectWithSync = {
|
|
201
|
+
getEntitiesConfig: jest.fn( () => ENTITIES_WITH_SYNC ),
|
|
202
|
+
getEditedEntityRecord: jest.fn( () =>
|
|
203
|
+
Promise.resolve( EDITED_RECORD )
|
|
204
|
+
),
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
triggerFetch.mockImplementation( () => ENTITY_RESPONSE );
|
|
208
|
+
|
|
209
|
+
await getEntityRecord(
|
|
210
|
+
'foo',
|
|
211
|
+
'bar',
|
|
212
|
+
1
|
|
213
|
+
)( {
|
|
214
|
+
dispatch,
|
|
215
|
+
registry,
|
|
216
|
+
resolveSelect: resolveSelectWithSync,
|
|
217
|
+
} );
|
|
218
|
+
|
|
219
|
+
// Extract the handlers passed to syncManager.load.
|
|
220
|
+
const handlers = syncManager.load.mock.calls[ 0 ][ 4 ];
|
|
221
|
+
|
|
222
|
+
// Call persistCRDTDoc and wait for the internal promise chain.
|
|
223
|
+
handlers.persistCRDTDoc();
|
|
224
|
+
await resolveSelectWithSync.getEditedEntityRecord();
|
|
225
|
+
|
|
226
|
+
// Should have fetched the full edited entity record.
|
|
227
|
+
expect(
|
|
228
|
+
resolveSelectWithSync.getEditedEntityRecord
|
|
229
|
+
).toHaveBeenCalledWith( 'foo', 'bar', 1 );
|
|
230
|
+
|
|
231
|
+
// Should not have called saveEntityRecord.
|
|
232
|
+
expect( dispatch.saveEntityRecord ).not.toHaveBeenCalled();
|
|
233
|
+
} );
|
|
234
|
+
|
|
235
|
+
it( 'persistCRDTDoc fetches edited record and saves full entity record', async () => {
|
|
236
|
+
const POST_RECORD = { id: 1, title: 'Test Post', meta: {} };
|
|
237
|
+
const EDITED_RECORD = { id: 1, title: 'Edited Post', meta: {} };
|
|
185
238
|
const POST_RESPONSE = {
|
|
186
239
|
json: () => Promise.resolve( POST_RECORD ),
|
|
187
240
|
};
|
|
@@ -219,8 +272,8 @@ describe( 'getEntityRecord', () => {
|
|
|
219
272
|
// Extract the handlers passed to syncManager.load.
|
|
220
273
|
const handlers = syncManager.load.mock.calls[ 0 ][ 4 ];
|
|
221
274
|
|
|
222
|
-
// Call
|
|
223
|
-
handlers.
|
|
275
|
+
// Call persistCRDTDoc and wait for the internal promise chain.
|
|
276
|
+
handlers.persistCRDTDoc();
|
|
224
277
|
await resolveSelectWithSync.getEditedEntityRecord();
|
|
225
278
|
|
|
226
279
|
// Should have fetched the full edited entity record.
|
|
@@ -236,8 +289,8 @@ describe( 'getEntityRecord', () => {
|
|
|
236
289
|
);
|
|
237
290
|
} );
|
|
238
291
|
|
|
239
|
-
it( '
|
|
240
|
-
const POST_RECORD = { id: 1, title: 'Test Post' };
|
|
292
|
+
it( 'persistCRDTDoc saves even when there are no unsaved edits', async () => {
|
|
293
|
+
const POST_RECORD = { id: 1, title: 'Test Post', meta: {} };
|
|
241
294
|
const POST_RESPONSE = {
|
|
242
295
|
json: () => Promise.resolve( POST_RECORD ),
|
|
243
296
|
};
|
|
@@ -275,8 +328,8 @@ describe( 'getEntityRecord', () => {
|
|
|
275
328
|
|
|
276
329
|
const handlers = syncManager.load.mock.calls[ 0 ][ 4 ];
|
|
277
330
|
|
|
278
|
-
// Call
|
|
279
|
-
handlers.
|
|
331
|
+
// Call persistCRDTDoc and wait for the internal promise chain.
|
|
332
|
+
handlers.persistCRDTDoc();
|
|
280
333
|
await resolveSelectWithSync.getEditedEntityRecord();
|
|
281
334
|
|
|
282
335
|
// Should save the record even with no edits (the whole point of the fix).
|
|
@@ -336,9 +389,9 @@ describe( 'getEntityRecord', () => {
|
|
|
336
389
|
editRecord: expect.any( Function ),
|
|
337
390
|
getEditedRecord: expect.any( Function ),
|
|
338
391
|
onStatusChange: expect.any( Function ),
|
|
392
|
+
persistCRDTDoc: expect.any( Function ),
|
|
339
393
|
refetchRecord: expect.any( Function ),
|
|
340
394
|
restoreUndoMeta: expect.any( Function ),
|
|
341
|
-
saveRecord: expect.any( Function ),
|
|
342
395
|
}
|
|
343
396
|
);
|
|
344
397
|
} );
|
|
@@ -832,8 +885,8 @@ describe( 'canUser', () => {
|
|
|
832
885
|
batch: ( callback ) => callback(),
|
|
833
886
|
};
|
|
834
887
|
dispatch = Object.assign( jest.fn(), {
|
|
835
|
-
|
|
836
|
-
|
|
888
|
+
receiveUserPermission: jest.fn(),
|
|
889
|
+
finishResolution: jest.fn(),
|
|
837
890
|
} );
|
|
838
891
|
triggerFetch.mockReset();
|
|
839
892
|
} );
|
|
@@ -859,7 +912,7 @@ describe( 'canUser', () => {
|
|
|
859
912
|
parse: false,
|
|
860
913
|
} );
|
|
861
914
|
|
|
862
|
-
expect( dispatch.
|
|
915
|
+
expect( dispatch.receiveUserPermission ).not.toHaveBeenCalled();
|
|
863
916
|
} );
|
|
864
917
|
|
|
865
918
|
it( 'throws an error when an entity resource object is malformed', async () => {
|
|
@@ -888,8 +941,9 @@ describe( 'canUser', () => {
|
|
|
888
941
|
parse: false,
|
|
889
942
|
} );
|
|
890
943
|
|
|
891
|
-
expect( dispatch.
|
|
892
|
-
|
|
944
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
945
|
+
'create/media',
|
|
946
|
+
false
|
|
893
947
|
);
|
|
894
948
|
} );
|
|
895
949
|
|
|
@@ -910,8 +964,9 @@ describe( 'canUser', () => {
|
|
|
910
964
|
parse: false,
|
|
911
965
|
} );
|
|
912
966
|
|
|
913
|
-
expect( dispatch.
|
|
914
|
-
|
|
967
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
968
|
+
'create/postType/attachment',
|
|
969
|
+
false
|
|
915
970
|
);
|
|
916
971
|
} );
|
|
917
972
|
|
|
@@ -931,8 +986,9 @@ describe( 'canUser', () => {
|
|
|
931
986
|
parse: false,
|
|
932
987
|
} );
|
|
933
988
|
|
|
934
|
-
expect( dispatch.
|
|
935
|
-
|
|
989
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
990
|
+
'create/media',
|
|
991
|
+
true
|
|
936
992
|
);
|
|
937
993
|
} );
|
|
938
994
|
|
|
@@ -953,8 +1009,9 @@ describe( 'canUser', () => {
|
|
|
953
1009
|
parse: false,
|
|
954
1010
|
} );
|
|
955
1011
|
|
|
956
|
-
expect( dispatch.
|
|
957
|
-
|
|
1012
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1013
|
+
'create/postType/attachment',
|
|
1014
|
+
true
|
|
958
1015
|
);
|
|
959
1016
|
} );
|
|
960
1017
|
|
|
@@ -975,8 +1032,9 @@ describe( 'canUser', () => {
|
|
|
975
1032
|
parse: false,
|
|
976
1033
|
} );
|
|
977
1034
|
|
|
978
|
-
expect( dispatch.
|
|
979
|
-
|
|
1035
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1036
|
+
'create/blocks/123',
|
|
1037
|
+
true
|
|
980
1038
|
);
|
|
981
1039
|
} );
|
|
982
1040
|
|
|
@@ -1001,8 +1059,9 @@ describe( 'canUser', () => {
|
|
|
1001
1059
|
parse: false,
|
|
1002
1060
|
} );
|
|
1003
1061
|
|
|
1004
|
-
expect( dispatch.
|
|
1005
|
-
|
|
1062
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1063
|
+
'create/postType/wp_block/123',
|
|
1064
|
+
true
|
|
1006
1065
|
);
|
|
1007
1066
|
} );
|
|
1008
1067
|
|
|
@@ -1029,11 +1088,13 @@ describe( 'canUser', () => {
|
|
|
1029
1088
|
|
|
1030
1089
|
expect( triggerFetch ).toHaveBeenCalledTimes( 1 );
|
|
1031
1090
|
|
|
1032
|
-
expect( dispatch.
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1091
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1092
|
+
'create/blocks',
|
|
1093
|
+
true
|
|
1094
|
+
);
|
|
1095
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1096
|
+
'read/blocks',
|
|
1097
|
+
true
|
|
1037
1098
|
);
|
|
1038
1099
|
} );
|
|
1039
1100
|
|
|
@@ -1068,11 +1129,13 @@ describe( 'canUser', () => {
|
|
|
1068
1129
|
|
|
1069
1130
|
expect( triggerFetch ).toHaveBeenCalledTimes( 1 );
|
|
1070
1131
|
|
|
1071
|
-
expect( dispatch.
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1132
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1133
|
+
'create/postType/wp_block',
|
|
1134
|
+
true
|
|
1135
|
+
);
|
|
1136
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1137
|
+
'read/postType/wp_block',
|
|
1138
|
+
true
|
|
1076
1139
|
);
|
|
1077
1140
|
} );
|
|
1078
1141
|
|
|
@@ -1105,13 +1168,21 @@ describe( 'canUser', () => {
|
|
|
1105
1168
|
'blocks'
|
|
1106
1169
|
)( { dispatch, registry, resolveSelect } );
|
|
1107
1170
|
|
|
1108
|
-
expect( dispatch.
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1171
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1172
|
+
'create/blocks',
|
|
1173
|
+
true
|
|
1174
|
+
);
|
|
1175
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1176
|
+
'read/blocks',
|
|
1177
|
+
true
|
|
1178
|
+
);
|
|
1179
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1180
|
+
'update/blocks',
|
|
1181
|
+
false
|
|
1182
|
+
);
|
|
1183
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1184
|
+
'delete/blocks',
|
|
1185
|
+
false
|
|
1115
1186
|
);
|
|
1116
1187
|
} );
|
|
1117
1188
|
|
|
@@ -1150,13 +1221,21 @@ describe( 'canUser', () => {
|
|
|
1150
1221
|
|
|
1151
1222
|
expect( triggerFetch ).toHaveBeenCalledTimes( 1 );
|
|
1152
1223
|
|
|
1153
|
-
expect( dispatch.
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1224
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1225
|
+
'create/blocks/123',
|
|
1226
|
+
true
|
|
1227
|
+
);
|
|
1228
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1229
|
+
'read/blocks/123',
|
|
1230
|
+
true
|
|
1231
|
+
);
|
|
1232
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1233
|
+
'update/blocks/123',
|
|
1234
|
+
true
|
|
1235
|
+
);
|
|
1236
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1237
|
+
'delete/blocks/123',
|
|
1238
|
+
true
|
|
1160
1239
|
);
|
|
1161
1240
|
} );
|
|
1162
1241
|
|
|
@@ -1195,13 +1274,21 @@ describe( 'canUser', () => {
|
|
|
1195
1274
|
|
|
1196
1275
|
expect( triggerFetch ).toHaveBeenCalledTimes( 1 );
|
|
1197
1276
|
|
|
1198
|
-
expect( dispatch.
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1277
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1278
|
+
'create/postType/wp_block/123',
|
|
1279
|
+
true
|
|
1280
|
+
);
|
|
1281
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1282
|
+
'read/postType/wp_block/123',
|
|
1283
|
+
true
|
|
1284
|
+
);
|
|
1285
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1286
|
+
'update/postType/wp_block/123',
|
|
1287
|
+
true
|
|
1288
|
+
);
|
|
1289
|
+
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
|
|
1290
|
+
'delete/postType/wp_block/123',
|
|
1291
|
+
true
|
|
1205
1292
|
);
|
|
1206
1293
|
} );
|
|
1207
1294
|
} );
|