@wordpress/core-data 7.30.1-next.836ecdcae.0 → 7.31.0
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 +2 -0
- package/README.md +23 -1
- package/build/actions.js +32 -2
- package/build/actions.js.map +1 -1
- package/build/entities.js +1 -1
- package/build/entities.js.map +1 -1
- package/build/entity-types/user.js.map +1 -1
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/use-entity-records.js.map +1 -1
- package/build/private-actions.js +8 -0
- package/build/private-actions.js.map +1 -1
- package/build/private-selectors.js +8 -1
- package/build/private-selectors.js.map +1 -1
- package/build/reducer.js +9 -1
- package/build/reducer.js.map +1 -1
- package/build/resolvers.js +80 -64
- package/build/resolvers.js.map +1 -1
- package/build/selectors.js +99 -41
- package/build/selectors.js.map +1 -1
- package/build-module/actions.js +32 -2
- package/build-module/actions.js.map +1 -1
- package/build-module/entities.js +1 -1
- package/build-module/entities.js.map +1 -1
- package/build-module/entity-types/user.js.map +1 -1
- package/build-module/hooks/index.js +8 -0
- package/build-module/hooks/index.js.map +1 -1
- package/build-module/hooks/use-entity-records.js.map +1 -1
- package/build-module/private-actions.js +7 -0
- package/build-module/private-actions.js.map +1 -1
- package/build-module/private-selectors.js +7 -1
- package/build-module/private-selectors.js.map +1 -1
- package/build-module/reducer.js +8 -1
- package/build-module/reducer.js.map +1 -1
- package/build-module/resolvers.js +76 -61
- package/build-module/resolvers.js.map +1 -1
- package/build-module/selectors.js +98 -41
- package/build-module/selectors.js.map +1 -1
- package/build-types/actions.d.ts.map +1 -1
- package/build-types/entity-types/user.d.ts +2 -2
- package/build-types/entity-types/user.d.ts.map +1 -1
- package/build-types/hooks/index.d.ts +8 -0
- package/build-types/hooks/index.d.ts.map +1 -1
- package/build-types/hooks/use-entity-records.d.ts +12 -2
- package/build-types/hooks/use-entity-records.d.ts.map +1 -1
- package/build-types/index.d.ts +2 -1
- package/build-types/index.d.ts.map +1 -1
- package/build-types/private-actions.d.ts +5 -0
- package/build-types/private-actions.d.ts.map +1 -1
- package/build-types/private-selectors.d.ts +1 -0
- package/build-types/private-selectors.d.ts.map +1 -1
- package/build-types/reducer.d.ts +3 -0
- package/build-types/reducer.d.ts.map +1 -1
- package/build-types/resolvers.d.ts +7 -0
- package/build-types/resolvers.d.ts.map +1 -1
- package/build-types/selectors.d.ts +18 -2
- package/build-types/selectors.d.ts.map +1 -1
- package/package.json +18 -18
- package/src/actions.js +43 -1
- package/src/entities.js +1 -1
- package/src/entity-types/user.ts +2 -2
- package/src/hooks/index.ts +9 -0
- package/src/hooks/use-entity-records.ts +12 -2
- package/src/private-actions.js +4 -0
- package/src/private-selectors.ts +10 -0
- package/src/reducer.js +7 -0
- package/src/resolvers.js +127 -81
- package/src/selectors.ts +110 -40
- package/src/test/actions.js +2 -2
- package/src/test/entities.js +32 -0
- package/src/test/resolvers.js +103 -12
- package/src/test/selectors.js +220 -13
- package/src/test/store.js +114 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/selectors.ts
CHANGED
|
@@ -36,7 +36,7 @@ export interface State {
|
|
|
36
36
|
blockPatternCategories: Array< unknown >;
|
|
37
37
|
currentGlobalStylesId: string;
|
|
38
38
|
currentTheme: string;
|
|
39
|
-
currentUser: ET.User< '
|
|
39
|
+
currentUser: ET.User< 'view' >;
|
|
40
40
|
embedPreviews: Record< string, { html: string } >;
|
|
41
41
|
entities: EntitiesState;
|
|
42
42
|
themeBaseGlobalStyles: Record< string, Object >;
|
|
@@ -49,6 +49,7 @@ export interface State {
|
|
|
49
49
|
userPatternCategories: Array< UserPatternCategory >;
|
|
50
50
|
defaultTemplates: Record< string, string >;
|
|
51
51
|
registeredPostMeta: Record< string, Object >;
|
|
52
|
+
templateAutoDraftId: Record< string, number | null >;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
type EntityRecordKey = string | number;
|
|
@@ -185,7 +186,7 @@ export function getAuthors(
|
|
|
185
186
|
*
|
|
186
187
|
* @return Current user object.
|
|
187
188
|
*/
|
|
188
|
-
export function getCurrentUser( state: State ): ET.User< '
|
|
189
|
+
export function getCurrentUser( state: State ): ET.User< 'view' > {
|
|
189
190
|
return state.currentUser;
|
|
190
191
|
}
|
|
191
192
|
|
|
@@ -358,6 +359,18 @@ export const getEntityRecord = createSelector(
|
|
|
358
359
|
): EntityRecord | undefined => {
|
|
359
360
|
logEntityDeprecation( kind, name, 'getEntityRecord' );
|
|
360
361
|
|
|
362
|
+
// For back-compat, we allow querying for static templates through
|
|
363
|
+
// wp_template.
|
|
364
|
+
if (
|
|
365
|
+
kind === 'postType' &&
|
|
366
|
+
name === 'wp_template' &&
|
|
367
|
+
typeof key === 'string' &&
|
|
368
|
+
// __experimentalGetDirtyEntityRecords always calls getEntityRecord
|
|
369
|
+
// with a string key, so we need that it's not a numeric ID.
|
|
370
|
+
! /^\d+$/.test( key )
|
|
371
|
+
) {
|
|
372
|
+
name = 'wp_registered_template';
|
|
373
|
+
}
|
|
361
374
|
const queriedState =
|
|
362
375
|
state.entities.records?.[ kind ]?.[ name ]?.queriedData;
|
|
363
376
|
if ( ! queriedState ) {
|
|
@@ -365,7 +378,7 @@ export const getEntityRecord = createSelector(
|
|
|
365
378
|
}
|
|
366
379
|
const context = query?.context ?? 'default';
|
|
367
380
|
|
|
368
|
-
if ( query
|
|
381
|
+
if ( ! query || ! query._fields ) {
|
|
369
382
|
// If expecting a complete item, validate that completeness.
|
|
370
383
|
if ( ! queriedState.itemIsComplete[ context ]?.[ key ] ) {
|
|
371
384
|
return undefined;
|
|
@@ -375,30 +388,29 @@ export const getEntityRecord = createSelector(
|
|
|
375
388
|
}
|
|
376
389
|
|
|
377
390
|
const item = queriedState.items[ context ]?.[ key ];
|
|
378
|
-
if ( item
|
|
379
|
-
|
|
380
|
-
const fields = getNormalizedCommaSeparable( query._fields ) ?? [];
|
|
381
|
-
for ( let f = 0; f < fields.length; f++ ) {
|
|
382
|
-
const field = fields[ f ].split( '.' );
|
|
383
|
-
let value = item;
|
|
384
|
-
field.forEach( ( fieldName ) => {
|
|
385
|
-
value = value?.[ fieldName ];
|
|
386
|
-
} );
|
|
387
|
-
setNestedValue( filteredItem, field, value );
|
|
388
|
-
}
|
|
389
|
-
return filteredItem as EntityRecord;
|
|
391
|
+
if ( ! item ) {
|
|
392
|
+
return item;
|
|
390
393
|
}
|
|
391
394
|
|
|
392
|
-
|
|
395
|
+
const filteredItem = {};
|
|
396
|
+
const fields = getNormalizedCommaSeparable( query._fields ) ?? [];
|
|
397
|
+
for ( let f = 0; f < fields.length; f++ ) {
|
|
398
|
+
const field = fields[ f ].split( '.' );
|
|
399
|
+
let value = item;
|
|
400
|
+
field.forEach( ( fieldName ) => {
|
|
401
|
+
value = value?.[ fieldName ];
|
|
402
|
+
} );
|
|
403
|
+
setNestedValue( filteredItem, field, value );
|
|
404
|
+
}
|
|
405
|
+
return filteredItem as EntityRecord;
|
|
393
406
|
} ) as GetEntityRecord,
|
|
394
407
|
( state: State, kind, name, recordId, query ) => {
|
|
395
408
|
const context = query?.context ?? 'default';
|
|
409
|
+
const queriedState =
|
|
410
|
+
state.entities.records?.[ kind ]?.[ name ]?.queriedData;
|
|
396
411
|
return [
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
]?.[ recordId ],
|
|
400
|
-
state.entities.records?.[ kind ]?.[ name ]?.queriedData
|
|
401
|
-
?.itemIsComplete[ context ]?.[ recordId ],
|
|
412
|
+
queriedState?.items[ context ]?.[ recordId ],
|
|
413
|
+
queriedState?.itemIsComplete[ context ]?.[ recordId ],
|
|
402
414
|
];
|
|
403
415
|
}
|
|
404
416
|
) as GetEntityRecord;
|
|
@@ -421,6 +433,62 @@ getEntityRecord.__unstableNormalizeArgs = (
|
|
|
421
433
|
return newArgs;
|
|
422
434
|
};
|
|
423
435
|
|
|
436
|
+
/**
|
|
437
|
+
* Returns true if a record has been received for the given set of parameters, or false otherwise.
|
|
438
|
+
*
|
|
439
|
+
* Note: This action does not trigger a request for the entity record from the API
|
|
440
|
+
* if it's not available in the local state.
|
|
441
|
+
*
|
|
442
|
+
* @param state State tree
|
|
443
|
+
* @param kind Entity kind.
|
|
444
|
+
* @param name Entity name.
|
|
445
|
+
* @param key Record's key.
|
|
446
|
+
* @param query Optional query.
|
|
447
|
+
*
|
|
448
|
+
* @return Whether an entity record has been received.
|
|
449
|
+
*/
|
|
450
|
+
export function hasEntityRecord(
|
|
451
|
+
state: State,
|
|
452
|
+
kind: string,
|
|
453
|
+
name: string,
|
|
454
|
+
key?: EntityRecordKey,
|
|
455
|
+
query?: GetRecordsHttpQuery
|
|
456
|
+
): boolean {
|
|
457
|
+
const queriedState =
|
|
458
|
+
state.entities.records?.[ kind ]?.[ name ]?.queriedData;
|
|
459
|
+
if ( ! queriedState ) {
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
const context = query?.context ?? 'default';
|
|
463
|
+
|
|
464
|
+
// If expecting a complete item, validate that completeness.
|
|
465
|
+
if ( ! query || ! query._fields ) {
|
|
466
|
+
return !! queriedState.itemIsComplete[ context ]?.[ key ];
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
const item = queriedState.items[ context ]?.[ key ];
|
|
470
|
+
if ( ! item ) {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// When `query._fields` is provided, check that each requested field exists,
|
|
475
|
+
// including any nested paths, on the item; return false if any part is missing.
|
|
476
|
+
const fields = getNormalizedCommaSeparable( query._fields ) ?? [];
|
|
477
|
+
for ( let i = 0; i < fields.length; i++ ) {
|
|
478
|
+
const path = fields[ i ].split( '.' );
|
|
479
|
+
let value = item;
|
|
480
|
+
for ( let p = 0; p < path.length; p++ ) {
|
|
481
|
+
const part = path[ p ];
|
|
482
|
+
if ( ! value || ! Object.hasOwn( value, part ) ) {
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
value = value[ part ];
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
return true;
|
|
490
|
+
}
|
|
491
|
+
|
|
424
492
|
/**
|
|
425
493
|
* Returns the Entity's record object by key. Doesn't trigger a resolver nor requests the entity records from the API if the entity record isn't available in the local state.
|
|
426
494
|
*
|
|
@@ -1488,7 +1556,7 @@ export const getRevision = createSelector(
|
|
|
1488
1556
|
|
|
1489
1557
|
const context = query?.context ?? 'default';
|
|
1490
1558
|
|
|
1491
|
-
if ( query
|
|
1559
|
+
if ( ! query || ! query._fields ) {
|
|
1492
1560
|
// If expecting a complete item, validate that completeness.
|
|
1493
1561
|
if ( ! queriedState.itemIsComplete[ context ]?.[ revisionKey ] ) {
|
|
1494
1562
|
return undefined;
|
|
@@ -1498,31 +1566,33 @@ export const getRevision = createSelector(
|
|
|
1498
1566
|
}
|
|
1499
1567
|
|
|
1500
1568
|
const item = queriedState.items[ context ]?.[ revisionKey ];
|
|
1501
|
-
if ( item
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
for ( let f = 0; f < fields.length; f++ ) {
|
|
1506
|
-
const field = fields[ f ].split( '.' );
|
|
1507
|
-
let value = item;
|
|
1508
|
-
field.forEach( ( fieldName ) => {
|
|
1509
|
-
value = value?.[ fieldName ];
|
|
1510
|
-
} );
|
|
1511
|
-
setNestedValue( filteredItem, field, value );
|
|
1512
|
-
}
|
|
1569
|
+
if ( ! item ) {
|
|
1570
|
+
return item;
|
|
1571
|
+
}
|
|
1513
1572
|
|
|
1514
|
-
|
|
1573
|
+
const filteredItem = {};
|
|
1574
|
+
const fields = getNormalizedCommaSeparable( query._fields ) ?? [];
|
|
1575
|
+
|
|
1576
|
+
for ( let f = 0; f < fields.length; f++ ) {
|
|
1577
|
+
const field = fields[ f ].split( '.' );
|
|
1578
|
+
let value = item;
|
|
1579
|
+
field.forEach( ( fieldName ) => {
|
|
1580
|
+
value = value?.[ fieldName ];
|
|
1581
|
+
} );
|
|
1582
|
+
setNestedValue( filteredItem, field, value );
|
|
1515
1583
|
}
|
|
1516
1584
|
|
|
1517
|
-
return
|
|
1585
|
+
return filteredItem;
|
|
1518
1586
|
},
|
|
1519
1587
|
( state: State, kind, name, recordKey, revisionKey, query ) => {
|
|
1520
1588
|
const context = query?.context ?? 'default';
|
|
1589
|
+
const queriedState =
|
|
1590
|
+
state.entities.records?.[ kind ]?.[ name ]?.revisions?.[
|
|
1591
|
+
recordKey
|
|
1592
|
+
];
|
|
1521
1593
|
return [
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
state.entities.records?.[ kind ]?.[ name ]?.revisions?.[ recordKey ]
|
|
1525
|
-
?.itemIsComplete?.[ context ]?.[ revisionKey ],
|
|
1594
|
+
queriedState?.items?.[ context ]?.[ revisionKey ],
|
|
1595
|
+
queriedState?.itemIsComplete?.[ context ]?.[ revisionKey ],
|
|
1526
1596
|
];
|
|
1527
1597
|
}
|
|
1528
1598
|
);
|
package/src/test/actions.js
CHANGED
|
@@ -38,14 +38,14 @@ describe( 'editEntityRecord', () => {
|
|
|
38
38
|
const select = {
|
|
39
39
|
getEntityConfig: jest.fn(),
|
|
40
40
|
};
|
|
41
|
-
const fulfillment = () =>
|
|
41
|
+
const fulfillment = async () =>
|
|
42
42
|
editEntityRecord(
|
|
43
43
|
entityConfig.kind,
|
|
44
44
|
entityConfig.name,
|
|
45
45
|
entityConfig.id,
|
|
46
46
|
{}
|
|
47
47
|
)( { select } );
|
|
48
|
-
expect( fulfillment ).toThrow(
|
|
48
|
+
await expect( fulfillment ).rejects.toThrow(
|
|
49
49
|
`The entity being edited (${ entityConfig.kind }, ${ entityConfig.name }) does not have a loaded config.`
|
|
50
50
|
);
|
|
51
51
|
expect( select.getEntityConfig ).toHaveBeenCalledTimes( 1 );
|
package/src/test/entities.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import apiFetch from '@wordpress/api-fetch';
|
|
5
|
+
|
|
6
|
+
jest.mock( '@wordpress/api-fetch' );
|
|
7
|
+
|
|
1
8
|
/**
|
|
2
9
|
* Internal dependencies
|
|
3
10
|
*/
|
|
@@ -5,6 +12,7 @@ import {
|
|
|
5
12
|
getMethodName,
|
|
6
13
|
rootEntitiesConfig,
|
|
7
14
|
prePersistPostType,
|
|
15
|
+
additionalEntityConfigLoaders,
|
|
8
16
|
} from '../entities';
|
|
9
17
|
|
|
10
18
|
describe( 'getMethodName', () => {
|
|
@@ -68,3 +76,27 @@ describe( 'prePersistPostType', () => {
|
|
|
68
76
|
expect( prePersistPostType( record, edits ) ).toEqual( {} );
|
|
69
77
|
} );
|
|
70
78
|
} );
|
|
79
|
+
|
|
80
|
+
describe( 'loadTaxonomyEntities', () => {
|
|
81
|
+
beforeEach( () => {
|
|
82
|
+
apiFetch.mockReset();
|
|
83
|
+
} );
|
|
84
|
+
|
|
85
|
+
it( 'should add supportsPagination: true to taxonomy entities', async () => {
|
|
86
|
+
const mockTaxonomies = {
|
|
87
|
+
category: {
|
|
88
|
+
name: 'Categories',
|
|
89
|
+
rest_base: 'categories',
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
apiFetch.mockResolvedValueOnce( mockTaxonomies );
|
|
94
|
+
|
|
95
|
+
const taxonomyLoader = additionalEntityConfigLoaders.find(
|
|
96
|
+
( loader ) => loader.kind === 'taxonomy'
|
|
97
|
+
);
|
|
98
|
+
const entities = await taxonomyLoader.loadEntities();
|
|
99
|
+
|
|
100
|
+
expect( entities[ 0 ].supportsPagination ).toBe( true );
|
|
101
|
+
} );
|
|
102
|
+
} );
|
package/src/test/resolvers.js
CHANGED
|
@@ -79,10 +79,6 @@ describe( 'getEntityRecord', () => {
|
|
|
79
79
|
it( 'accepts a query that overrides default api path', async () => {
|
|
80
80
|
const query = { context: 'view', _envelope: '1' };
|
|
81
81
|
|
|
82
|
-
const select = {
|
|
83
|
-
hasEntityRecords: jest.fn( () => {} ),
|
|
84
|
-
};
|
|
85
|
-
|
|
86
82
|
// Provide response
|
|
87
83
|
triggerFetch.mockImplementation( () => POST_TYPE_RESPONSE );
|
|
88
84
|
|
|
@@ -91,7 +87,7 @@ describe( 'getEntityRecord', () => {
|
|
|
91
87
|
'postType',
|
|
92
88
|
'post',
|
|
93
89
|
query
|
|
94
|
-
)( { dispatch,
|
|
90
|
+
)( { dispatch, registry, resolveSelect } );
|
|
95
91
|
|
|
96
92
|
// Trigger apiFetch, test that the query is present in the url.
|
|
97
93
|
expect( triggerFetch ).toHaveBeenCalledWith( {
|
|
@@ -241,7 +237,7 @@ describe( 'getEntityRecords', () => {
|
|
|
241
237
|
] );
|
|
242
238
|
} );
|
|
243
239
|
|
|
244
|
-
it( 'caches permissions
|
|
240
|
+
it( 'caches permissions and marks entity records as resolved when using _fields', async () => {
|
|
245
241
|
const finishResolutions = jest.fn();
|
|
246
242
|
const dispatch = Object.assign( jest.fn(), {
|
|
247
243
|
receiveEntityRecords: jest.fn(),
|
|
@@ -285,9 +281,7 @@ describe( 'getEntityRecords', () => {
|
|
|
285
281
|
'canUser',
|
|
286
282
|
expect.any( Array )
|
|
287
283
|
);
|
|
288
|
-
|
|
289
|
-
// But individual entity records should NOT be marked as resolved
|
|
290
|
-
expect( finishResolutions ).not.toHaveBeenCalledWith(
|
|
284
|
+
expect( finishResolutions ).toHaveBeenCalledWith(
|
|
291
285
|
'getEntityRecord',
|
|
292
286
|
expect.any( Array )
|
|
293
287
|
);
|
|
@@ -328,15 +322,112 @@ describe( 'getEntityRecords', () => {
|
|
|
328
322
|
'canUser',
|
|
329
323
|
expect.any( Array )
|
|
330
324
|
);
|
|
331
|
-
|
|
332
|
-
// Individual entity records should NOT be marked as resolved
|
|
333
|
-
expect( finishResolutions ).not.toHaveBeenCalledWith(
|
|
325
|
+
expect( finishResolutions ).toHaveBeenCalledWith(
|
|
334
326
|
'getEntityRecord',
|
|
335
327
|
expect.any( Array )
|
|
336
328
|
);
|
|
337
329
|
} );
|
|
338
330
|
} );
|
|
339
331
|
|
|
332
|
+
describe( 'taxonomy pagination', () => {
|
|
333
|
+
const registry = { batch: ( callback ) => callback() };
|
|
334
|
+
let dispatch, loadedTaxonomyEntities;
|
|
335
|
+
|
|
336
|
+
beforeEach( async () => {
|
|
337
|
+
dispatch = Object.assign( jest.fn(), {
|
|
338
|
+
receiveEntityRecords: jest.fn(),
|
|
339
|
+
__unstableAcquireStoreLock: jest.fn().mockResolvedValue( 'lock' ),
|
|
340
|
+
__unstableReleaseStoreLock: jest.fn(),
|
|
341
|
+
} );
|
|
342
|
+
triggerFetch.mockReset();
|
|
343
|
+
|
|
344
|
+
const mockTaxonomyConfig = {
|
|
345
|
+
category: {
|
|
346
|
+
name: 'Categories',
|
|
347
|
+
rest_base: 'categories',
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
triggerFetch.mockResolvedValueOnce( mockTaxonomyConfig );
|
|
352
|
+
|
|
353
|
+
const { additionalEntityConfigLoaders } = await import( '../entities' );
|
|
354
|
+
const taxonomyLoader = additionalEntityConfigLoaders.find(
|
|
355
|
+
( loader ) => loader.kind === 'taxonomy'
|
|
356
|
+
);
|
|
357
|
+
loadedTaxonomyEntities = await taxonomyLoader.loadEntities();
|
|
358
|
+
} );
|
|
359
|
+
|
|
360
|
+
it( 'should make paginated API calls with parse: false', async () => {
|
|
361
|
+
const resolveSelect = {
|
|
362
|
+
getEntitiesConfig: jest
|
|
363
|
+
.fn()
|
|
364
|
+
.mockResolvedValue( loadedTaxonomyEntities ),
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
triggerFetch.mockResolvedValueOnce( [
|
|
368
|
+
{ id: 1, name: 'Category 1' },
|
|
369
|
+
{ id: 2, name: 'Category 2' },
|
|
370
|
+
] );
|
|
371
|
+
|
|
372
|
+
await getEntityRecords( 'taxonomy', 'category', {
|
|
373
|
+
per_page: 2,
|
|
374
|
+
page: 1,
|
|
375
|
+
} )( { dispatch, registry, resolveSelect } );
|
|
376
|
+
|
|
377
|
+
expect( triggerFetch ).toHaveBeenLastCalledWith( {
|
|
378
|
+
path: '/wp/v2/categories?context=edit&per_page=2&page=1',
|
|
379
|
+
parse: false,
|
|
380
|
+
} );
|
|
381
|
+
} );
|
|
382
|
+
|
|
383
|
+
it( 'should extract pagination metadata from headers', async () => {
|
|
384
|
+
const resolveSelect = {
|
|
385
|
+
getEntitiesConfig: jest
|
|
386
|
+
.fn()
|
|
387
|
+
.mockResolvedValue( loadedTaxonomyEntities ),
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
const mockResponse = {
|
|
391
|
+
json: () =>
|
|
392
|
+
Promise.resolve( [
|
|
393
|
+
{ id: 1, name: 'Category 1' },
|
|
394
|
+
{ id: 2, name: 'Category 2' },
|
|
395
|
+
] ),
|
|
396
|
+
headers: {
|
|
397
|
+
get: jest.fn( ( header ) => {
|
|
398
|
+
if ( header === 'X-WP-Total' ) {
|
|
399
|
+
return '10';
|
|
400
|
+
}
|
|
401
|
+
if ( header === 'X-WP-TotalPages' ) {
|
|
402
|
+
return '5';
|
|
403
|
+
}
|
|
404
|
+
return null;
|
|
405
|
+
} ),
|
|
406
|
+
},
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
triggerFetch.mockResolvedValueOnce( mockResponse );
|
|
410
|
+
|
|
411
|
+
await getEntityRecords( 'taxonomy', 'category', {
|
|
412
|
+
per_page: 2,
|
|
413
|
+
page: 1,
|
|
414
|
+
} )( { dispatch, registry, resolveSelect } );
|
|
415
|
+
|
|
416
|
+
expect( dispatch.receiveEntityRecords ).toHaveBeenCalledWith(
|
|
417
|
+
'taxonomy',
|
|
418
|
+
'category',
|
|
419
|
+
[
|
|
420
|
+
{ id: 1, name: 'Category 1' },
|
|
421
|
+
{ id: 2, name: 'Category 2' },
|
|
422
|
+
],
|
|
423
|
+
{ per_page: 2, page: 1 },
|
|
424
|
+
false,
|
|
425
|
+
undefined,
|
|
426
|
+
{ totalItems: 10, totalPages: 5 }
|
|
427
|
+
);
|
|
428
|
+
} );
|
|
429
|
+
} );
|
|
430
|
+
|
|
340
431
|
describe( 'getEmbedPreview', () => {
|
|
341
432
|
const SUCCESSFUL_EMBED_RESPONSE = { data: '<p>some html</p>' };
|
|
342
433
|
const UNEMBEDDABLE_RESPONSE = false;
|