@wordpress/core-data 7.27.0 → 7.28.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +2 -2
  3. package/build/actions.js +7 -0
  4. package/build/actions.js.map +1 -1
  5. package/build/entities.js +15 -2
  6. package/build/entities.js.map +1 -1
  7. package/build/hooks/use-resource-permissions.js +1 -1
  8. package/build/hooks/use-resource-permissions.js.map +1 -1
  9. package/build/index.js +50 -8
  10. package/build/index.js.map +1 -1
  11. package/build/private-actions.js +99 -0
  12. package/build/private-actions.js.map +1 -1
  13. package/build/private-selectors.js +3 -0
  14. package/build/private-selectors.js.map +1 -1
  15. package/build/resolvers.js +1 -1
  16. package/build/resolvers.js.map +1 -1
  17. package/build/selectors.js +26 -1
  18. package/build/selectors.js.map +1 -1
  19. package/build/utils/log-entity-deprecation.js +63 -0
  20. package/build/utils/log-entity-deprecation.js.map +1 -0
  21. package/build-module/actions.js +7 -0
  22. package/build-module/actions.js.map +1 -1
  23. package/build-module/entities.js +14 -1
  24. package/build-module/entities.js.map +1 -1
  25. package/build-module/hooks/use-resource-permissions.js +1 -1
  26. package/build-module/hooks/use-resource-permissions.js.map +1 -1
  27. package/build-module/index.js +50 -8
  28. package/build-module/index.js.map +1 -1
  29. package/build-module/private-actions.js +96 -0
  30. package/build-module/private-actions.js.map +1 -1
  31. package/build-module/private-selectors.js +2 -0
  32. package/build-module/private-selectors.js.map +1 -1
  33. package/build-module/resolvers.js +1 -1
  34. package/build-module/resolvers.js.map +1 -1
  35. package/build-module/selectors.js +26 -1
  36. package/build-module/selectors.js.map +1 -1
  37. package/build-module/utils/log-entity-deprecation.js +55 -0
  38. package/build-module/utils/log-entity-deprecation.js.map +1 -0
  39. package/build-types/actions.d.ts.map +1 -1
  40. package/build-types/entities.d.ts +29 -18
  41. package/build-types/entities.d.ts.map +1 -1
  42. package/build-types/index.d.ts.map +1 -1
  43. package/build-types/private-actions.d.ts +24 -0
  44. package/build-types/private-actions.d.ts.map +1 -1
  45. package/build-types/private-selectors.d.ts +1 -1
  46. package/build-types/private-selectors.d.ts.map +1 -1
  47. package/build-types/reducer.d.ts +3 -3
  48. package/build-types/reducer.d.ts.map +1 -1
  49. package/build-types/selectors.d.ts +1 -1
  50. package/build-types/selectors.d.ts.map +1 -1
  51. package/build-types/utils/log-entity-deprecation.d.ts +15 -0
  52. package/build-types/utils/log-entity-deprecation.d.ts.map +1 -0
  53. package/package.json +18 -18
  54. package/src/actions.js +11 -0
  55. package/src/entities.js +14 -0
  56. package/src/hooks/test/use-resource-permissions.js +3 -3
  57. package/src/hooks/use-resource-permissions.ts +1 -1
  58. package/src/index.js +54 -14
  59. package/src/private-actions.js +118 -0
  60. package/src/private-selectors.ts +2 -0
  61. package/src/resolvers.js +1 -1
  62. package/src/selectors.ts +29 -1
  63. package/src/test/deprecated-entity-logging.js +291 -0
  64. package/src/test/private-actions.js +213 -0
  65. package/src/test/resolvers.js +7 -7
  66. package/src/test/selectors.js +18 -7
  67. package/src/utils/log-entity-deprecation.ts +67 -0
  68. package/src/utils/test/log-entity-deprecation.js +130 -0
  69. package/tsconfig.tsbuildinfo +1 -1
@@ -1,3 +1,13 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import apiFetch from '@wordpress/api-fetch';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { STORE_NAME } from './name';
10
+
1
11
  /**
2
12
  * Returns an action object used in signalling that the registered post meta
3
13
  * fields for a post type have been received.
@@ -14,3 +24,111 @@ export function receiveRegisteredPostMeta( postType, registeredPostMeta ) {
14
24
  registeredPostMeta,
15
25
  };
16
26
  }
27
+
28
+ /**
29
+ * @typedef {Object} Modifier
30
+ * @property {string} [type] - The type of modifier.
31
+ * @property {Object} [args] - The arguments of the modifier.
32
+ */
33
+
34
+ /**
35
+ * @typedef {Object} Edits
36
+ * @property {string} [src] - The URL of the media item.
37
+ * @property {Modifier[]} [modifiers] - The modifiers to apply to the media item.
38
+ */
39
+
40
+ /**
41
+ * Duplicates a media (attachment) entity record and, optionally, modifies it.
42
+ *
43
+ * @param {string} recordId Entity record ID.
44
+ * @param {Edits} edits Edits to apply to the record.
45
+ * @param {Object} options Options object.
46
+ * @param {Function} options.__unstableFetch Custom fetch function.
47
+ * @param {boolean} options.throwOnError Whether to throw an error if the request fails.
48
+ *
49
+ * @return {Promise} Promise resolving to the updated record.
50
+ */
51
+ export const editMediaEntity =
52
+ (
53
+ recordId,
54
+ edits = {},
55
+ { __unstableFetch = apiFetch, throwOnError = false } = {}
56
+ ) =>
57
+ async ( { dispatch, resolveSelect } ) => {
58
+ if ( ! recordId ) {
59
+ return;
60
+ }
61
+
62
+ const kind = 'postType';
63
+ const name = 'attachment';
64
+
65
+ const configs = await resolveSelect.getEntitiesConfig( kind );
66
+ const entityConfig = configs.find(
67
+ ( config ) => config.kind === kind && config.name === name
68
+ );
69
+
70
+ if ( ! entityConfig ) {
71
+ return;
72
+ }
73
+
74
+ const lock = await dispatch.__unstableAcquireStoreLock(
75
+ STORE_NAME,
76
+ [ 'entities', 'records', kind, name, recordId ],
77
+ { exclusive: true }
78
+ );
79
+
80
+ let updatedRecord;
81
+ let error;
82
+ let hasError = false;
83
+
84
+ try {
85
+ dispatch( {
86
+ type: 'SAVE_ENTITY_RECORD_START',
87
+ kind,
88
+ name,
89
+ recordId,
90
+ } );
91
+
92
+ try {
93
+ const path = `${ entityConfig.baseURL }/${ recordId }/edit`;
94
+ const newRecord = await __unstableFetch( {
95
+ path,
96
+ method: 'POST',
97
+ data: {
98
+ ...edits,
99
+ },
100
+ } );
101
+
102
+ if ( newRecord ) {
103
+ dispatch.receiveEntityRecords(
104
+ kind,
105
+ name,
106
+ [ newRecord ],
107
+ undefined,
108
+ true,
109
+ undefined,
110
+ undefined
111
+ );
112
+ updatedRecord = newRecord;
113
+ }
114
+ } catch ( e ) {
115
+ error = e;
116
+ hasError = true;
117
+ }
118
+
119
+ dispatch( {
120
+ type: 'SAVE_ENTITY_RECORD_FINISH',
121
+ kind,
122
+ name,
123
+ recordId,
124
+ error,
125
+ } );
126
+
127
+ if ( hasError && throwOnError ) {
128
+ throw error;
129
+ }
130
+ return updatedRecord;
131
+ } finally {
132
+ dispatch.__unstableReleaseStoreLock( lock );
133
+ }
134
+ };
@@ -9,6 +9,7 @@ import { createSelector, createRegistrySelector } from '@wordpress/data';
9
9
  import { getDefaultTemplateId, getEntityRecord, type State } from './selectors';
10
10
  import { STORE_NAME } from './name';
11
11
  import { unlock } from './lock-unlock';
12
+ import logEntityDeprecation from './utils/log-entity-deprecation';
12
13
 
13
14
  type EntityRecordKey = string | number;
14
15
 
@@ -97,6 +98,7 @@ export function getEntityRecordPermissions(
97
98
  name: string,
98
99
  id: string
99
100
  ) {
101
+ logEntityDeprecation( kind, name, 'getEntityRecordPermissions' );
100
102
  return getEntityRecordsPermissions( state, kind, name, id )[ 0 ];
101
103
  }
102
104
 
package/src/resolvers.js CHANGED
@@ -479,7 +479,7 @@ export const getEmbedPreview =
479
479
  *
480
480
  * @param {string} requestedAction Action to check. One of: 'create', 'read', 'update',
481
481
  * 'delete'.
482
- * @param {string|Object} resource Entity resource to check. Accepts entity object `{ kind: 'root', name: 'media', id: 1 }`
482
+ * @param {string|Object} resource Entity resource to check. Accepts entity object `{ kind: 'postType', name: 'attachment', id: 1 }`
483
483
  * or REST base as a string - `media`.
484
484
  * @param {?string} id ID of the rest resource to check.
485
485
  */
package/src/selectors.ts CHANGED
@@ -24,6 +24,7 @@ import {
24
24
  } from './utils';
25
25
  import type * as ET from './entity-types';
26
26
  import type { UndoManager } from '@wordpress/undo-manager';
27
+ import logEntityDeprecation from './utils/log-entity-deprecation';
27
28
 
28
29
  // This is an incomplete, high-level approximation of the State type.
29
30
  // It makes the selectors slightly more safe, but is intended to evolve
@@ -272,6 +273,8 @@ export function getEntityConfig(
272
273
  kind: string,
273
274
  name: string
274
275
  ): any {
276
+ logEntityDeprecation( kind, name, 'getEntityConfig' );
277
+
275
278
  return state.entities.config?.find(
276
279
  ( config ) => config.kind === kind && config.name === name
277
280
  );
@@ -353,6 +356,8 @@ export const getEntityRecord = createSelector(
353
356
  key?: EntityRecordKey,
354
357
  query?: GetRecordsHttpQuery
355
358
  ): EntityRecord | undefined => {
359
+ logEntityDeprecation( kind, name, 'getEntityRecord' );
360
+
356
361
  const queriedState =
357
362
  state.entities.records?.[ kind ]?.[ name ]?.queriedData;
358
363
  if ( ! queriedState ) {
@@ -450,6 +455,8 @@ export const getRawEntityRecord = createSelector(
450
455
  name: string,
451
456
  key: EntityRecordKey
452
457
  ): EntityRecord | undefined => {
458
+ logEntityDeprecation( kind, name, 'getRawEntityRecord' );
459
+
453
460
  const record = getEntityRecord< EntityRecord >(
454
461
  state,
455
462
  kind,
@@ -512,6 +519,7 @@ export function hasEntityRecords(
512
519
  name: string,
513
520
  query?: GetRecordsHttpQuery
514
521
  ): boolean {
522
+ logEntityDeprecation( kind, name, 'hasEntityRecords' );
515
523
  return Array.isArray( getEntityRecords( state, kind, name, query ) );
516
524
  }
517
525
 
@@ -567,6 +575,8 @@ export const getEntityRecords = ( <
567
575
  name: string,
568
576
  query: GetRecordsHttpQuery
569
577
  ): EntityRecord[] | null => {
578
+ logEntityDeprecation( kind, name, 'getEntityRecords' );
579
+
570
580
  // Queried data state is prepopulated for all known entities. If this is not
571
581
  // assigned for the given parameters, then it is known to not exist.
572
582
  const queriedState =
@@ -594,6 +604,8 @@ export const getEntityRecordsTotalItems = (
594
604
  name: string,
595
605
  query: GetRecordsHttpQuery
596
606
  ): number | null => {
607
+ logEntityDeprecation( kind, name, 'getEntityRecordsTotalItems' );
608
+
597
609
  // Queried data state is prepopulated for all known entities. If this is not
598
610
  // assigned for the given parameters, then it is known to not exist.
599
611
  const queriedState =
@@ -621,6 +633,8 @@ export const getEntityRecordsTotalPages = (
621
633
  name: string,
622
634
  query: GetRecordsHttpQuery
623
635
  ): number | null => {
636
+ logEntityDeprecation( kind, name, 'getEntityRecordsTotalPages' );
637
+
624
638
  // Queried data state is prepopulated for all known entities. If this is not
625
639
  // assigned for the given parameters, then it is known to not exist.
626
640
  const queriedState =
@@ -774,6 +788,7 @@ export function getEntityRecordEdits(
774
788
  name: string,
775
789
  recordId: EntityRecordKey
776
790
  ): Optional< any > {
791
+ logEntityDeprecation( kind, name, 'getEntityRecordEdits' );
777
792
  return state.entities.records?.[ kind ]?.[ name ]?.edits?.[
778
793
  recordId as string | number
779
794
  ];
@@ -800,6 +815,7 @@ export const getEntityRecordNonTransientEdits = createSelector(
800
815
  name: string,
801
816
  recordId: EntityRecordKey
802
817
  ): Optional< any > => {
818
+ logEntityDeprecation( kind, name, 'getEntityRecordNonTransientEdits' );
803
819
  const { transientEdits } = getEntityConfig( state, kind, name ) || {};
804
820
  const edits = getEntityRecordEdits( state, kind, name, recordId ) || {};
805
821
  if ( ! transientEdits ) {
@@ -835,6 +851,7 @@ export function hasEditsForEntityRecord(
835
851
  name: string,
836
852
  recordId: EntityRecordKey
837
853
  ): boolean {
854
+ logEntityDeprecation( kind, name, 'hasEditsForEntityRecord' );
838
855
  return (
839
856
  isSavingEntityRecord( state, kind, name, recordId ) ||
840
857
  Object.keys(
@@ -860,6 +877,7 @@ export const getEditedEntityRecord = createSelector(
860
877
  name: string,
861
878
  recordId: EntityRecordKey
862
879
  ): ET.Updatable< EntityRecord > | false => {
880
+ logEntityDeprecation( kind, name, 'getEditedEntityRecord' );
863
881
  const raw = getRawEntityRecord( state, kind, name, recordId );
864
882
  const edited = getEntityRecordEdits( state, kind, name, recordId );
865
883
  // Never return a non-falsy empty object. Unfortunately we can't return
@@ -910,6 +928,7 @@ export function isAutosavingEntityRecord(
910
928
  name: string,
911
929
  recordId: EntityRecordKey
912
930
  ): boolean {
931
+ logEntityDeprecation( kind, name, 'isAutosavingEntityRecord' );
913
932
  const { pending, isAutosave } =
914
933
  state.entities.records?.[ kind ]?.[ name ]?.saving?.[ recordId ] ?? {};
915
934
  return Boolean( pending && isAutosave );
@@ -931,6 +950,7 @@ export function isSavingEntityRecord(
931
950
  name: string,
932
951
  recordId: EntityRecordKey
933
952
  ): boolean {
953
+ logEntityDeprecation( kind, name, 'isSavingEntityRecord' );
934
954
  return (
935
955
  state.entities.records?.[ kind ]?.[ name ]?.saving?.[
936
956
  recordId as EntityRecordKey
@@ -954,6 +974,7 @@ export function isDeletingEntityRecord(
954
974
  name: string,
955
975
  recordId: EntityRecordKey
956
976
  ): boolean {
977
+ logEntityDeprecation( kind, name, 'isDeletingEntityRecord' );
957
978
  return (
958
979
  state.entities.records?.[ kind ]?.[ name ]?.deleting?.[
959
980
  recordId as EntityRecordKey
@@ -977,6 +998,7 @@ export function getLastEntitySaveError(
977
998
  name: string,
978
999
  recordId: EntityRecordKey
979
1000
  ): any {
1001
+ logEntityDeprecation( kind, name, 'getLastEntitySaveError' );
980
1002
  return state.entities.records?.[ kind ]?.[ name ]?.saving?.[ recordId ]
981
1003
  ?.error;
982
1004
  }
@@ -997,6 +1019,7 @@ export function getLastEntityDeleteError(
997
1019
  name: string,
998
1020
  recordId: EntityRecordKey
999
1021
  ): any {
1022
+ logEntityDeprecation( kind, name, 'getLastEntityDeleteError' );
1000
1023
  return state.entities.records?.[ kind ]?.[ name ]?.deleting?.[ recordId ]
1001
1024
  ?.error;
1002
1025
  }
@@ -1143,7 +1166,7 @@ export function isPreviewEmbedFallback( state: State, url: string ): boolean {
1143
1166
  *
1144
1167
  * @param state Data state.
1145
1168
  * @param action Action to check. One of: 'create', 'read', 'update', 'delete'.
1146
- * @param resource Entity resource to check. Accepts entity object `{ kind: 'root', name: 'media', id: 1 }`
1169
+ * @param resource Entity resource to check. Accepts entity object `{ kind: 'postType', name: 'attachment', id: 1 }`
1147
1170
  * or REST base as a string - `media`.
1148
1171
  * @param id Optional ID of the rest resource to check.
1149
1172
  *
@@ -1160,6 +1183,9 @@ export function canUser(
1160
1183
  if ( isEntity && ( ! resource.kind || ! resource.name ) ) {
1161
1184
  return false;
1162
1185
  }
1186
+ if ( isEntity ) {
1187
+ logEntityDeprecation( resource.kind, resource.name, 'canUser' );
1188
+ }
1163
1189
 
1164
1190
  const key = getUserPermissionCacheKey( action, resource, id );
1165
1191
 
@@ -1418,6 +1444,7 @@ export const getRevisions = (
1418
1444
  recordKey: EntityRecordKey,
1419
1445
  query?: GetRecordsHttpQuery
1420
1446
  ): RevisionRecord[] | null => {
1447
+ logEntityDeprecation( kind, name, 'getRevisions' );
1421
1448
  const queriedStateRevisions =
1422
1449
  state.entities.records?.[ kind ]?.[ name ]?.revisions?.[ recordKey ];
1423
1450
  if ( ! queriedStateRevisions ) {
@@ -1449,6 +1476,7 @@ export const getRevision = createSelector(
1449
1476
  revisionKey: EntityRecordKey,
1450
1477
  query?: GetRecordsHttpQuery
1451
1478
  ): RevisionRecord | Record< PropertyKey, never > | undefined => {
1479
+ logEntityDeprecation( kind, name, 'getRevision' );
1452
1480
  const queriedState =
1453
1481
  state.entities.records?.[ kind ]?.[ name ]?.revisions?.[
1454
1482
  recordKey
@@ -0,0 +1,291 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import deprecated from '@wordpress/deprecated';
5
+ import { createRegistry } from '@wordpress/data';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { store as coreDataStore } from '../index';
11
+
12
+ jest.mock( '@wordpress/deprecated' );
13
+ jest.mock( '@wordpress/api-fetch' );
14
+
15
+ // Use fake timers within this file.
16
+ // logEntityDeprecation() uses setTimeout() to avoid spurious logging, so fake timers are used to
17
+ // ensure that the deprecation warning is logged correctly.
18
+ jest.useFakeTimers();
19
+
20
+ /**
21
+ * Returns the expected arguments for the deprecated function call.
22
+ *
23
+ * @param {string} name - The name of the function.
24
+ * @param {Array} args - The arguments for the function.
25
+ * @param {boolean} isShorthandSelector - Whether the function is a shorthand selector.
26
+ * @param {string} alternativeFunction - The name of the alternative function.
27
+ * @return {Array} The expected arguments for the deprecated function call.
28
+ */
29
+ function getExpectedDeprecationArgs(
30
+ name,
31
+ args,
32
+ isShorthandSelector,
33
+ alternativeFunction
34
+ ) {
35
+ const expectedMessage = isShorthandSelector
36
+ ? `'${ name }'`
37
+ : `The 'root', 'media' entity (used via '${ name }')`;
38
+
39
+ let expectedAlternative = "the 'postType', 'attachment' entity";
40
+ if ( alternativeFunction ) {
41
+ expectedAlternative += ` via the '${ alternativeFunction }' function`;
42
+ }
43
+
44
+ return [
45
+ expectedMessage,
46
+ {
47
+ alternative: expectedAlternative,
48
+ since: '6.9',
49
+ },
50
+ ];
51
+ }
52
+
53
+ /**
54
+ * Creates a test registry with the core-data store and sets up the deprecated media entity.
55
+ *
56
+ * This approach enables testing generated selections/actions (like `getMedia`), and simplifies
57
+ * the tests by avoiding an endless amount of mocks.
58
+ *
59
+ * It means the tests in this file are integration rather than unit tests, so they're kept
60
+ * separate from the selector.js/reducer.js tests.
61
+ *
62
+ * @return {Object} Registry with core-data store registered.
63
+ */
64
+ function createTestRegistry() {
65
+ const registry = createRegistry();
66
+
67
+ // Register the core-data store
68
+ registry.register( coreDataStore );
69
+
70
+ // Set up the deprecated media entity configuration
71
+ const mediaEntityConfig = {
72
+ name: 'media',
73
+ kind: 'root',
74
+ baseURL: '/wp/v2/media',
75
+ baseURLParams: { context: 'edit' },
76
+ plural: 'mediaItems',
77
+ label: 'Media',
78
+ rawAttributes: [ 'caption', 'title', 'description' ],
79
+ supportsPagination: true,
80
+ };
81
+
82
+ // Add the media entity to the store
83
+ registry.dispatch( coreDataStore ).addEntities( [ mediaEntityConfig ] );
84
+
85
+ // Add a sample media record to the store for testing
86
+ const mediaRecord = {
87
+ id: '123',
88
+ title: 'Test Media',
89
+ content: 'Test content',
90
+ excerpt: 'Test excerpt',
91
+ };
92
+
93
+ registry
94
+ .dispatch( coreDataStore )
95
+ .receiveEntityRecords( 'root', 'media', mediaRecord );
96
+
97
+ jest.runAllTimers();
98
+
99
+ return registry;
100
+ }
101
+
102
+ describe( 'Deprecated entity logging', () => {
103
+ describe.each( [
104
+ {
105
+ type: 'selector',
106
+ name: 'getEntityConfig',
107
+ args: [ 'root', 'media' ],
108
+ },
109
+ {
110
+ type: 'selector',
111
+ name: 'getEntityRecord',
112
+ args: [ 'root', 'media', '123' ],
113
+ },
114
+ {
115
+ type: 'selector',
116
+ name: 'getRawEntityRecord',
117
+ args: [ 'root', 'media', '123' ],
118
+ },
119
+ {
120
+ type: 'selector',
121
+ name: 'hasEntityRecords',
122
+ args: [ 'root', 'media' ],
123
+ },
124
+ {
125
+ type: 'selector',
126
+ name: 'getEntityRecords',
127
+ args: [ 'root', 'media' ],
128
+ },
129
+ {
130
+ type: 'selector',
131
+ name: 'getEntityRecordsTotalItems',
132
+ args: [ 'root', 'media', { _fields: 'title' } ],
133
+ },
134
+ {
135
+ type: 'selector',
136
+ name: 'getEntityRecordsTotalPages',
137
+ args: [ 'root', 'media', { _fields: 'title' } ],
138
+ },
139
+ {
140
+ type: 'selector',
141
+ name: 'getEntityRecordEdits',
142
+ args: [ 'root', 'media', '123' ],
143
+ },
144
+ {
145
+ type: 'selector',
146
+ name: 'getEntityRecordNonTransientEdits',
147
+ args: [ 'root', 'media', '123' ],
148
+ },
149
+ {
150
+ type: 'selector',
151
+ name: 'hasEditsForEntityRecord',
152
+ args: [ 'root', 'media', '123' ],
153
+ },
154
+ {
155
+ type: 'selector',
156
+ name: 'getEditedEntityRecord',
157
+ args: [ 'root', 'media', '123' ],
158
+ },
159
+ {
160
+ type: 'selector',
161
+ name: 'isAutosavingEntityRecord',
162
+ args: [ 'root', 'media', '123' ],
163
+ },
164
+ {
165
+ type: 'selector',
166
+ name: 'isSavingEntityRecord',
167
+ args: [ 'root', 'media', '123' ],
168
+ },
169
+ {
170
+ type: 'selector',
171
+ name: 'isDeletingEntityRecord',
172
+ args: [ 'root', 'media', '123' ],
173
+ },
174
+ {
175
+ type: 'selector',
176
+ name: 'getLastEntitySaveError',
177
+ args: [ 'root', 'media', '123' ],
178
+ },
179
+ {
180
+ type: 'selector',
181
+ name: 'getLastEntityDeleteError',
182
+ args: [ 'root', 'media', '123' ],
183
+ },
184
+ {
185
+ type: 'selector',
186
+ name: 'canUser',
187
+ args: [ 'create', { kind: 'root', name: 'media' }, '123' ],
188
+ },
189
+ {
190
+ type: 'selector',
191
+ name: 'getRevisions',
192
+ args: [ 'root', 'media', '123' ],
193
+ },
194
+ {
195
+ type: 'selector',
196
+ name: 'getRevision',
197
+ args: [ 'root', 'media', '123', '10' ],
198
+ },
199
+ {
200
+ type: 'selector',
201
+ name: 'getMedia',
202
+ args: [ '123' ],
203
+ isShorthandSelector: true,
204
+ alternativeFunction: 'getEntityRecord',
205
+ },
206
+ {
207
+ type: 'selector',
208
+ name: 'getMediaItems',
209
+ args: [],
210
+ isShorthandSelector: true,
211
+ alternativeFunction: 'getEntityRecords',
212
+ },
213
+ {
214
+ type: 'action',
215
+ name: 'deleteEntityRecord',
216
+ args: [ 'root', 'media', '123' ],
217
+ },
218
+ {
219
+ type: 'action',
220
+ name: 'editEntityRecord',
221
+ args: [ 'root', 'media', '123', { title: 'Media' } ],
222
+ },
223
+ {
224
+ type: 'action',
225
+ name: 'saveEntityRecord',
226
+ args: [ 'root', 'media', { title: 'Media' } ],
227
+ },
228
+ {
229
+ type: 'action',
230
+ name: 'saveEditedEntityRecord',
231
+ args: [ 'root', 'media', '123' ],
232
+ },
233
+ {
234
+ type: 'action',
235
+ name: '__experimentalSaveSpecifiedEntityEdits',
236
+ args: [ 'root', 'media', '123', [ 'title' ] ],
237
+ },
238
+ {
239
+ type: 'action',
240
+ name: 'receiveRevisions',
241
+ args: [ 'root', 'media', '123', [ 'title' ] ],
242
+ },
243
+ {
244
+ type: 'action',
245
+ name: 'saveMedia',
246
+ args: [ { title: 'Media' } ],
247
+ alternativeFunction: 'saveEntityRecord',
248
+ isShorthandSelector: true,
249
+ },
250
+ {
251
+ type: 'action',
252
+ name: 'deleteMedia',
253
+ args: [ '123' ],
254
+ alternativeFunction: 'deleteEntityRecord',
255
+ isShorthandSelector: true,
256
+ },
257
+ ] )(
258
+ '$name $type',
259
+ ( { type, name, args, alternativeFunction, isShorthandSelector } ) => {
260
+ beforeEach( () => {
261
+ deprecated.mockReset();
262
+ } );
263
+
264
+ it( 'logs a deprecation warning when used with deprecated entities', () => {
265
+ // Create a test registry with the actual store
266
+ const registry = createTestRegistry();
267
+
268
+ if ( type === 'selector' ) {
269
+ // Dispatch the action.
270
+ registry.select( coreDataStore )[ name ]( ...args );
271
+ } else {
272
+ // Dispatch the action.
273
+ registry.dispatch( coreDataStore )[ name ]( ...args );
274
+ }
275
+
276
+ const [ expectedMessage, expectedOptions ] =
277
+ getExpectedDeprecationArgs(
278
+ name,
279
+ args,
280
+ isShorthandSelector,
281
+ alternativeFunction
282
+ );
283
+
284
+ expect( deprecated ).toHaveBeenCalledWith(
285
+ expectedMessage,
286
+ expectedOptions
287
+ );
288
+ } );
289
+ }
290
+ );
291
+ } );