@wordpress/editor 12.2.1 → 12.2.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.
Files changed (65) hide show
  1. package/build/components/local-autosave-monitor/index.js +5 -5
  2. package/build/components/local-autosave-monitor/index.js.map +1 -1
  3. package/build/components/post-saved-state/index.js +1 -1
  4. package/build/components/post-saved-state/index.js.map +1 -1
  5. package/build/components/post-switch-to-draft-button/index.js +19 -14
  6. package/build/components/post-switch-to-draft-button/index.js.map +1 -1
  7. package/build/components/post-trash/index.js +15 -29
  8. package/build/components/post-trash/index.js.map +1 -1
  9. package/build/components/provider/index.native.js +17 -8
  10. package/build/components/provider/index.native.js.map +1 -1
  11. package/build/components/provider/use-block-editor-settings.js +3 -2
  12. package/build/components/provider/use-block-editor-settings.js.map +1 -1
  13. package/build/store/actions.js +231 -225
  14. package/build/store/actions.js.map +1 -1
  15. package/build/store/actions.native.js +6 -4
  16. package/build/store/actions.native.js.map +1 -1
  17. package/build/store/index.js +1 -8
  18. package/build/store/index.js.map +1 -1
  19. package/build/store/{controls.js → local-autosave.js} +1 -18
  20. package/build/store/local-autosave.js.map +1 -0
  21. package/build/store/reducer.js +0 -2
  22. package/build/store/reducer.js.map +1 -1
  23. package/build/store/utils/notice-builder.js +5 -0
  24. package/build/store/utils/notice-builder.js.map +1 -1
  25. package/build-module/components/local-autosave-monitor/index.js +1 -1
  26. package/build-module/components/local-autosave-monitor/index.js.map +1 -1
  27. package/build-module/components/post-saved-state/index.js +1 -1
  28. package/build-module/components/post-saved-state/index.js.map +1 -1
  29. package/build-module/components/post-switch-to-draft-button/index.js +22 -16
  30. package/build-module/components/post-switch-to-draft-button/index.js.map +1 -1
  31. package/build-module/components/post-trash/index.js +15 -27
  32. package/build-module/components/post-trash/index.js.map +1 -1
  33. package/build-module/components/provider/index.native.js +19 -10
  34. package/build-module/components/provider/index.native.js.map +1 -1
  35. package/build-module/components/provider/use-block-editor-settings.js +3 -2
  36. package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
  37. package/build-module/store/actions.js +208 -207
  38. package/build-module/store/actions.js.map +1 -1
  39. package/build-module/store/actions.native.js +3 -3
  40. package/build-module/store/actions.native.js.map +1 -1
  41. package/build-module/store/index.js +1 -6
  42. package/build-module/store/index.js.map +1 -1
  43. package/build-module/store/{controls.js → local-autosave.js} +1 -15
  44. package/build-module/store/local-autosave.js.map +1 -0
  45. package/build-module/store/reducer.js +0 -2
  46. package/build-module/store/reducer.js.map +1 -1
  47. package/build-module/store/utils/notice-builder.js +5 -0
  48. package/build-module/store/utils/notice-builder.js.map +1 -1
  49. package/package.json +14 -15
  50. package/src/components/local-autosave-monitor/index.js +4 -1
  51. package/src/components/post-saved-state/index.js +1 -1
  52. package/src/components/post-switch-to-draft-button/index.js +35 -24
  53. package/src/components/post-trash/index.js +12 -24
  54. package/src/components/provider/index.native.js +20 -16
  55. package/src/components/provider/use-block-editor-settings.js +2 -0
  56. package/src/store/actions.js +137 -249
  57. package/src/store/actions.native.js +3 -3
  58. package/src/store/index.js +0 -6
  59. package/src/store/{controls.js → local-autosave.js} +0 -8
  60. package/src/store/reducer.js +0 -2
  61. package/src/store/test/actions.js +244 -416
  62. package/src/store/utils/notice-builder.js +5 -0
  63. package/src/store/utils/test/notice-builder.js +1 -0
  64. package/build/store/controls.js.map +0 -1
  65. package/build-module/store/controls.js.map +0 -1
@@ -1,461 +1,289 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { apiFetch } from '@wordpress/data-controls';
5
- import { controls } from '@wordpress/data';
4
+ import apiFetch from '@wordpress/api-fetch';
5
+ import { store as blockEditorStore } from '@wordpress/block-editor';
6
+ import { store as coreStore } from '@wordpress/core-data';
7
+ import { createRegistry } from '@wordpress/data';
6
8
  import { store as noticesStore } from '@wordpress/notices';
7
9
 
8
10
  /**
9
11
  * Internal dependencies
10
12
  */
13
+
11
14
  import * as actions from '../actions';
12
- import { STORE_NAME, TRASH_POST_NOTICE_ID } from '../constants';
15
+ import { store as editorStore } from '..';
16
+
17
+ jest.useRealTimers();
18
+
19
+ const postId = 44;
13
20
 
14
- const postType = {
21
+ const postTypeConfig = {
22
+ kind: 'postType',
23
+ name: 'post',
24
+ baseURL: '/wp/v2/posts',
25
+ transientEdits: { blocks: true, selection: true },
26
+ mergedEdits: { meta: true },
27
+ rawAttributes: [ 'title', 'excerpt', 'content' ],
28
+ };
29
+
30
+ const postTypeEntity = {
31
+ slug: 'post',
15
32
  rest_base: 'posts',
16
33
  labels: {
17
34
  item_updated: 'Updated Post',
18
35
  item_published: 'Post published',
36
+ item_reverted_to_draft: 'Post reverted to draft.',
19
37
  },
20
38
  };
21
- const postId = 44;
22
- const postTypeSlug = 'post';
23
39
 
24
- describe( 'Post generator actions', () => {
40
+ function createRegistryWithStores() {
41
+ // create a registry
42
+ const registry = createRegistry();
43
+
44
+ // register stores
45
+ registry.register( blockEditorStore );
46
+ registry.register( coreStore );
47
+ registry.register( editorStore );
48
+ registry.register( noticesStore );
49
+
50
+ // register post type entity
51
+ registry.dispatch( coreStore ).addEntities( [ postTypeConfig ] );
52
+
53
+ // store post type entity
54
+ registry
55
+ .dispatch( coreStore )
56
+ .receiveEntityRecords( 'root', 'postType', [ postTypeEntity ] );
57
+
58
+ return registry;
59
+ }
60
+
61
+ const getMethod = ( options ) =>
62
+ options.headers?.[ 'X-HTTP-Method-Override' ] || options.method || 'GET';
63
+
64
+ describe( 'Post actions', () => {
25
65
  describe( 'savePost()', () => {
26
- let fulfillment, currentPost, currentPostStatus, isAutosave;
27
- beforeEach( () => {
28
- currentPost = () => ( {
66
+ it( 'saves a modified post', async () => {
67
+ const post = {
29
68
  id: postId,
30
- type: postTypeSlug,
69
+ type: 'post',
31
70
  title: 'bar',
32
71
  content: 'bar',
33
72
  excerpt: 'crackers',
34
- status: currentPostStatus,
35
- } );
36
- } );
37
- const reset = ( isAutosaving ) =>
38
- ( fulfillment = actions.savePost( { isAutosave: isAutosaving } ) );
39
- const testConditions = [
40
- [
41
- 'yields an action for checking if the post is saveable',
42
- () => true,
43
- () => {
44
- reset( isAutosave );
45
- const { value } = fulfillment.next();
46
- expect( value ).toEqual(
47
- controls.select( STORE_NAME, 'isEditedPostSaveable' )
48
- );
49
- },
50
- ],
51
- [
52
- 'yields an action for selecting the current edited post content',
53
- () => true,
54
- () => {
55
- const { value } = fulfillment.next( true );
56
- expect( value ).toEqual(
57
- controls.select( STORE_NAME, 'getEditedPostContent' )
58
- );
59
- },
60
- ],
61
- [
62
- "yields an action for editing the post entity's content if not an autosave",
63
- () => true,
64
- () => {
65
- if ( ! isAutosave ) {
66
- const edits = { content: currentPost().content };
67
- const { value } = fulfillment.next( edits.content );
68
- expect( value ).toEqual(
69
- controls.dispatch( STORE_NAME, 'editPost', edits, {
70
- undoIgnore: true,
71
- } )
72
- );
73
- }
74
- },
75
- ],
76
- [
77
- 'yields an action for signalling that an update to the post started',
78
- () => true,
79
- () => {
80
- const { value } = fulfillment.next();
81
- expect( value ).toEqual( {
82
- type: 'REQUEST_POST_UPDATE_START',
83
- options: { isAutosave },
84
- } );
85
- },
86
- ],
87
- [
88
- 'yields an action for selecting the current post',
89
- () => true,
90
- () => {
91
- const { value } = fulfillment.next();
92
- expect( value ).toEqual(
93
- controls.select( STORE_NAME, 'getCurrentPost' )
94
- );
95
- },
96
- ],
97
- [
98
- "yields an action for selecting the post entity's non transient edits",
99
- () => true,
100
- () => {
101
- const post = currentPost();
102
- const { value } = fulfillment.next( post );
103
- expect( value ).toEqual(
104
- controls.select(
105
- 'core',
106
- 'getEntityRecordNonTransientEdits',
107
- 'postType',
108
- post.type,
109
- post.id
110
- )
111
- );
112
- },
113
- ],
114
- [
115
- 'yields an action for dispatching an update to the post entity',
116
- () => true,
117
- () => {
118
- const post = currentPost();
119
- const { value } = fulfillment.next( post );
120
- expect( value ).toEqual(
121
- controls.dispatch(
122
- 'core',
123
- 'saveEntityRecord',
124
- 'postType',
125
- post.type,
126
- isAutosave ? { ...post, content: undefined } : post,
127
- {
128
- isAutosave,
129
- }
130
- )
131
- );
132
- },
133
- ],
134
- [
135
- 'yields an action for signalling that an update to the post finished',
136
- () => true,
137
- () => {
138
- const { value } = fulfillment.next();
139
- expect( value ).toEqual( {
140
- type: 'REQUEST_POST_UPDATE_FINISH',
141
- options: { isAutosave },
142
- } );
143
- },
144
- ],
145
- [
146
- "yields an action for selecting the entity's save error",
147
- () => true,
148
- () => {
149
- const post = currentPost();
150
- const { value } = fulfillment.next();
151
- expect( value ).toEqual(
152
- controls.select(
153
- 'core',
154
- 'getLastEntitySaveError',
155
- 'postType',
156
- post.type,
157
- post.id
158
- )
159
- );
160
- },
161
- ],
162
- [
163
- 'yields an action for selecting the current post',
164
- () => true,
165
- () => {
166
- const { value } = fulfillment.next();
167
- expect( value ).toEqual(
168
- controls.select( STORE_NAME, 'getCurrentPost' )
169
- );
170
- },
171
- ],
172
- [
173
- 'yields an action for selecting the current post type config',
174
- () => true,
175
- () => {
176
- const post = currentPost();
177
- const { value } = fulfillment.next( post );
178
- expect( value ).toEqual(
179
- controls.resolveSelect(
180
- 'core',
181
- 'getPostType',
182
- post.type
183
- )
184
- );
185
- },
186
- ],
187
- [
188
- 'yields an action for dispatching a success notice',
189
- () => true,
190
- () => {
191
- if ( ! isAutosave ) {
192
- const { value } = fulfillment.next( postType );
193
- expect( value ).toEqual(
194
- controls.dispatch(
195
- noticesStore,
196
- 'createSuccessNotice',
197
- currentPostStatus === 'publish'
198
- ? 'Updated Post'
199
- : 'Draft saved',
200
- {
201
- actions: [],
202
- id: 'SAVE_POST_NOTICE_ID',
203
- type: 'snackbar',
204
- }
205
- )
206
- );
207
- }
208
- },
209
- ],
210
- [
211
- 'yields an action for marking the last change as persistent',
212
- () => true,
213
- () => {
214
- if ( ! isAutosave ) {
215
- const { value } = fulfillment.next();
216
- expect( value ).toEqual(
217
- controls.dispatch(
218
- 'core/block-editor',
219
- '__unstableMarkLastChangeAsPersistent'
220
- )
221
- );
222
- }
223
- },
224
- ],
225
- [
226
- 'implicitly returns undefined',
227
- () => true,
228
- () => {
229
- expect( fulfillment.next() ).toEqual( {
230
- done: true,
231
- value: undefined,
232
- } );
233
- },
234
- ],
235
- ];
236
-
237
- const conditionalRunTestRoutine = ( isAutosaving ) => ( [
238
- testDescription,
239
- shouldRun,
240
- testRoutine,
241
- ] ) => {
242
- if ( shouldRun( isAutosaving ) ) {
243
- // eslint-disable-next-line jest/valid-title
244
- it( testDescription, () => {
245
- testRoutine();
246
- } );
247
- }
248
- };
249
-
250
- describe( 'yields with expected responses for when not autosaving and edited post is new', () => {
251
- beforeEach( () => {
252
- isAutosave = false;
253
- currentPostStatus = 'draft';
254
- } );
255
- testConditions.forEach( conditionalRunTestRoutine( false ) );
256
- } );
73
+ status: 'draft',
74
+ };
75
+
76
+ // mock apiFetch response
77
+ apiFetch.setFetchHandler( async ( options ) => {
78
+ const method = getMethod( options );
79
+ const { path, data } = options;
257
80
 
258
- describe( 'yields with expected responses for when not autosaving and edited post is not new', () => {
259
- beforeEach( () => {
260
- isAutosave = false;
261
- currentPostStatus = 'publish';
81
+ if (
82
+ method === 'PUT' &&
83
+ path.startsWith( `/wp/v2/posts/${ postId }` )
84
+ ) {
85
+ return { ...post, ...data };
86
+ }
87
+
88
+ throw {
89
+ code: 'unknown_path',
90
+ message: `Unknown path: ${ method } ${ path }`,
91
+ };
262
92
  } );
263
- testConditions.forEach( conditionalRunTestRoutine( false ) );
264
- } );
265
- describe( 'yields with expected responses for when autosaving is true and edited post is not new', () => {
266
- beforeEach( () => {
267
- isAutosave = true;
268
- currentPostStatus = 'autosave';
93
+
94
+ // create registry
95
+ const registry = createRegistryWithStores();
96
+
97
+ // store post
98
+ registry
99
+ .dispatch( coreStore )
100
+ .receiveEntityRecords( 'postType', 'post', post );
101
+
102
+ // setup editor with post and initial edits
103
+ registry.dispatch( editorStore ).setupEditor( post, {
104
+ content: 'new bar',
269
105
  } );
270
- testConditions.forEach( conditionalRunTestRoutine( true ) );
271
- } );
272
- } );
273
- describe( 'autosave()', () => {
274
- it( 'dispatches savePost with the correct arguments', () => {
275
- const fulfillment = actions.autosave();
276
- const { value } = fulfillment.next();
277
- expect( value.actionName ).toBe( 'savePost' );
278
- expect( value.args ).toEqual( [ { isAutosave: true } ] );
279
- } );
280
- } );
281
- describe( 'trashPost()', () => {
282
- let fulfillment;
283
- const currentPost = { id: 10, content: 'foo', status: 'publish' };
284
- const reset = () => ( fulfillment = actions.trashPost() );
285
- const rewind = () => {
286
- reset();
287
- fulfillment.next();
288
- fulfillment.next( postTypeSlug );
289
- fulfillment.next( postType );
290
- fulfillment.next();
291
- fulfillment.next( currentPost );
292
- };
293
- it( 'yields expected action for selecting the current post type slug', () => {
294
- reset();
295
- const { value } = fulfillment.next();
296
- expect( value ).toEqual(
297
- controls.select( STORE_NAME, 'getCurrentPostType' )
298
- );
299
- } );
300
- it( 'yields expected action for selecting the post type object', () => {
301
- const { value } = fulfillment.next( postTypeSlug );
302
- expect( value ).toEqual(
303
- controls.resolveSelect( 'core', 'getPostType', postTypeSlug )
304
- );
305
- } );
306
- it(
307
- 'yields expected action for dispatching removing the trash notice ' +
308
- 'for the post',
309
- () => {
310
- const { value } = fulfillment.next( postType );
311
- expect( value ).toEqual(
312
- controls.dispatch(
313
- noticesStore,
314
- 'removeNotice',
315
- TRASH_POST_NOTICE_ID
316
- )
317
- );
318
- }
319
- );
320
- it( 'yields expected action for selecting the currentPost', () => {
321
- const { value } = fulfillment.next();
322
- expect( value ).toEqual(
323
- controls.select( STORE_NAME, 'getCurrentPost' )
324
- );
325
- } );
326
- it( 'yields expected action object for the api fetch', () => {
327
- const { value } = fulfillment.next( currentPost );
328
- expect( value ).toEqual(
329
- apiFetch( {
330
- path: `/wp/v2/${ postType.rest_base }/${ currentPost.id }`,
331
- method: 'DELETE',
332
- } )
106
+
107
+ // check that the post is dirty
108
+ expect( registry.select( editorStore ).isEditedPostDirty() ).toBe(
109
+ true
333
110
  );
334
- } );
335
- describe( 'expected yields when fetch throws an error', () => {
336
- it( 'yields expected action for dispatching an error notice', () => {
337
- const error = { foo: 'bar', code: 'fail' };
338
- const { value } = fulfillment.throw( error );
339
- expect( value ).toEqual(
340
- controls.dispatch(
341
- noticesStore,
342
- 'createErrorNotice',
343
- 'Trashing failed',
344
- {
345
- id: TRASH_POST_NOTICE_ID,
346
- }
347
- )
348
- );
349
- } );
350
- } );
351
- describe( 'expected yields when fetch does not throw an error', () => {
352
- it( 'yields expected dispatch action for saving the post', () => {
353
- rewind();
354
- const { value } = fulfillment.next();
355
- expect( value ).toEqual(
356
- controls.dispatch( STORE_NAME, 'savePost' )
357
- );
358
- } );
359
- } );
360
- } );
361
- } );
362
111
 
363
- describe( 'Editor actions', () => {
364
- describe( 'setupEditor()', () => {
365
- it( 'should yield the setup editor actions but not reset blocks when the template is empty', () => {
366
- const post = { content: { raw: '' }, status: 'publish' };
367
- const fulfillment = actions.setupEditor( post );
368
- let { value } = fulfillment.next();
369
- expect( value ).toEqual( actions.resetPost( post ) );
370
- value = fulfillment.next().value;
371
- expect( value ).toEqual( {
372
- type: 'SETUP_EDITOR',
373
- post: { content: { raw: '' }, status: 'publish' },
374
- } );
375
- value = fulfillment.next().value;
376
- expect( value ).toEqual(
377
- actions.setupEditorState( {
378
- content: { raw: '' },
379
- status: 'publish',
380
- } )
112
+ // save the post
113
+ await registry.dispatch( editorStore ).savePost();
114
+
115
+ // check the new content
116
+ const content = registry
117
+ .select( editorStore )
118
+ .getEditedPostContent();
119
+ expect( content ).toBe( 'new bar' );
120
+
121
+ // check that the post is no longer dirty
122
+ expect( registry.select( editorStore ).isEditedPostDirty() ).toBe(
123
+ false
381
124
  );
382
- } );
383
- } );
384
125
 
385
- describe( 'resetPost', () => {
386
- it( 'should return the RESET_POST action', () => {
387
- const post = {};
388
- const result = actions.resetPost( post );
389
- expect( result ).toEqual( {
390
- type: 'RESET_POST',
391
- post,
392
- } );
126
+ // check that a success notice has been shown
127
+ const notices = registry.select( noticesStore ).getNotices();
128
+ expect( notices ).toMatchObject( [
129
+ {
130
+ status: 'success',
131
+ content: 'Draft saved',
132
+ },
133
+ ] );
393
134
  } );
394
135
  } );
395
136
 
396
- describe( 'requestPostUpdateStart', () => {
397
- it( 'should return the REQUEST_POST_UPDATE_START action', () => {
398
- const result = actions.__experimentalRequestPostUpdateStart();
399
- expect( result ).toEqual( {
400
- type: 'REQUEST_POST_UPDATE_START',
401
- options: {},
402
- } );
403
- } );
404
- } );
137
+ describe( 'autosave()', () => {
138
+ it( 'autosaves a modified post', async () => {
139
+ const post = {
140
+ id: postId,
141
+ type: 'post',
142
+ title: 'bar',
143
+ content: 'bar',
144
+ excerpt: 'crackers',
145
+ status: 'draft',
146
+ };
405
147
 
406
- describe( 'editPost', () => {
407
- it( 'should edit the relevant entity record', () => {
408
- const edits = { format: 'sample' };
409
- const fulfillment = actions.editPost( edits );
410
- expect( fulfillment.next() ).toEqual( {
411
- done: false,
412
- value: controls.select( STORE_NAME, 'getCurrentPost' ),
413
- } );
414
- const post = { id: 1, type: 'post' };
415
- expect( fulfillment.next( post ) ).toEqual( {
416
- done: false,
417
- value: controls.dispatch(
418
- 'core',
419
- 'editEntityRecord',
420
- 'postType',
421
- post.type,
422
- post.id,
423
- edits,
424
- undefined
425
- ),
148
+ // mock apiFetch response
149
+ apiFetch.setFetchHandler( async ( options ) => {
150
+ const method = getMethod( options );
151
+ const { path, data } = options;
152
+
153
+ if (
154
+ method === 'GET' &&
155
+ path.startsWith( '/wp/v2/users/me' )
156
+ ) {
157
+ return { id: 1 };
158
+ } else if (
159
+ path.startsWith( `/wp/v2/posts/${ postId }/autosaves` )
160
+ ) {
161
+ if ( method === 'POST' ) {
162
+ return { ...post, ...data };
163
+ } else if ( method === 'GET' ) {
164
+ return [];
165
+ }
166
+ }
167
+
168
+ throw {
169
+ code: 'unknown_path',
170
+ message: `Unknown path: ${ method } ${ path }`,
171
+ };
426
172
  } );
427
- expect( fulfillment.next() ).toEqual( {
428
- done: true,
429
- value: undefined,
173
+
174
+ // create registry
175
+ const registry = createRegistryWithStores();
176
+
177
+ // set current user
178
+ registry.dispatch( coreStore ).receiveCurrentUser( { id: 1 } );
179
+
180
+ // store post
181
+ registry
182
+ .dispatch( coreStore )
183
+ .receiveEntityRecords( 'postType', 'post', post );
184
+
185
+ // setup editor with post and initial edits
186
+ registry.dispatch( editorStore ).setupEditor( post, {
187
+ content: 'new bar',
430
188
  } );
189
+
190
+ // check that the post is dirty
191
+ expect( registry.select( editorStore ).isEditedPostDirty() ).toBe(
192
+ true
193
+ );
194
+
195
+ // autosave the post
196
+ await registry.dispatch( editorStore ).autosave();
197
+
198
+ // check the new content
199
+ const content = registry
200
+ .select( editorStore )
201
+ .getEditedPostContent();
202
+ expect( content ).toBe( 'new bar' );
203
+
204
+ // check that the post is no longer dirty
205
+ expect( registry.select( editorStore ).isEditedPostDirty() ).toBe(
206
+ false
207
+ );
208
+
209
+ // check that no notice has been shown on autosave
210
+ const notices = registry.select( noticesStore ).getNotices();
211
+ expect( notices ).toMatchObject( [] );
431
212
  } );
432
213
  } );
433
214
 
434
- describe( 'redo', () => {
435
- it( 'should yield the REDO action', () => {
436
- const fulfillment = actions.redo();
437
- expect( fulfillment.next() ).toEqual( {
438
- done: false,
439
- value: controls.dispatch( 'core', 'redo' ),
440
- } );
441
- expect( fulfillment.next() ).toEqual( {
442
- done: true,
443
- value: undefined,
215
+ describe( 'trashPost()', () => {
216
+ it( 'trashes a post', async () => {
217
+ const post = {
218
+ id: postId,
219
+ type: 'post',
220
+ content: 'foo',
221
+ status: 'publish',
222
+ };
223
+
224
+ let gotTrashed = false;
225
+
226
+ // mock apiFetch response
227
+ apiFetch.setFetchHandler( async ( options ) => {
228
+ const method = getMethod( options );
229
+ const { path, data } = options;
230
+
231
+ if ( path.startsWith( `/wp/v2/posts/${ postId }` ) ) {
232
+ if ( method === 'DELETE' ) {
233
+ gotTrashed = true;
234
+ return { ...post, status: 'trash' };
235
+ } else if ( method === 'PUT' ) {
236
+ return {
237
+ ...post,
238
+ ...( gotTrashed && { status: 'trash' } ),
239
+ ...data,
240
+ };
241
+ }
242
+ }
243
+
244
+ throw {
245
+ code: 'unknown_path',
246
+ message: `Unknown path: ${ path }`,
247
+ };
444
248
  } );
249
+
250
+ // create registry
251
+ const registry = createRegistryWithStores();
252
+
253
+ // store post
254
+ registry
255
+ .dispatch( coreStore )
256
+ .receiveEntityRecords( 'postType', 'post', post );
257
+
258
+ // setup editor with post
259
+ registry.dispatch( editorStore ).setupEditor( post );
260
+
261
+ // trash the post
262
+ await registry.dispatch( editorStore ).trashPost();
263
+
264
+ // check that there are no notices
265
+ const notices = registry.select( noticesStore ).getNotices();
266
+ expect( notices ).toEqual( [] );
267
+
268
+ // check the new status
269
+ const { status } = registry.select( editorStore ).getCurrentPost();
270
+ expect( status ).toBe( 'trash' );
445
271
  } );
446
272
  } );
273
+ } );
447
274
 
448
- describe( 'undo', () => {
449
- it( 'should yield the UNDO action', () => {
450
- const fulfillment = actions.undo();
451
- expect( fulfillment.next() ).toEqual( {
452
- done: false,
453
- value: controls.dispatch( 'core', 'undo' ),
454
- } );
455
- expect( fulfillment.next() ).toEqual( {
456
- done: true,
457
- value: undefined,
458
- } );
275
+ describe( 'Editor actions', () => {
276
+ describe( 'setupEditor()', () => {
277
+ it( 'should setup the editor', () => {
278
+ // create registry
279
+ const registry = createRegistryWithStores();
280
+
281
+ registry
282
+ .dispatch( editorStore )
283
+ .setupEditor( { id: 10, type: 'post' } );
284
+ expect( registry.select( editorStore ).getCurrentPostId() ).toBe(
285
+ 10
286
+ );
459
287
  } );
460
288
  } );
461
289