@wordpress/abilities 0.2.1-next.8b30e05b0.0 → 0.2.1-next.8fd3f8831.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 (83) hide show
  1. package/README.md +32 -40
  2. package/build/{api.js → api.cjs} +22 -69
  3. package/build/api.cjs.map +7 -0
  4. package/build/{index.js → index.cjs} +4 -4
  5. package/build/{index.js.map → index.cjs.map} +2 -2
  6. package/build/store/{actions.js → actions.cjs} +43 -33
  7. package/build/store/actions.cjs.map +7 -0
  8. package/build/store/{constants.js → constants.cjs} +7 -16
  9. package/build/store/constants.cjs.map +7 -0
  10. package/build/store/{index.js → index.cjs} +6 -32
  11. package/build/store/index.cjs.map +7 -0
  12. package/build/store/{reducer.js → reducer.cjs} +4 -24
  13. package/build/store/reducer.cjs.map +7 -0
  14. package/build/store/{selectors.js → selectors.cjs} +2 -2
  15. package/build/store/selectors.cjs.map +7 -0
  16. package/build/store/types.cjs +19 -0
  17. package/build/store/types.cjs.map +7 -0
  18. package/build/{types.js → types.cjs} +1 -1
  19. package/build/types.cjs.map +7 -0
  20. package/build/{validation.js → validation.cjs} +3 -3
  21. package/build-module/api.js +22 -59
  22. package/build-module/api.js.map +2 -2
  23. package/build-module/index.js +3 -3
  24. package/build-module/index.js.map +2 -2
  25. package/build-module/store/actions.js +44 -33
  26. package/build-module/store/actions.js.map +2 -2
  27. package/build-module/store/constants.js +4 -10
  28. package/build-module/store/constants.js.map +2 -2
  29. package/build-module/store/index.js +6 -37
  30. package/build-module/store/index.js.map +2 -2
  31. package/build-module/store/reducer.js +3 -25
  32. package/build-module/store/reducer.js.map +2 -2
  33. package/build-module/store/selectors.js +1 -1
  34. package/build-module/store/selectors.js.map +2 -2
  35. package/build-module/store/types.js +1 -0
  36. package/build-module/store/types.js.map +7 -0
  37. package/build-types/api.d.ts +16 -23
  38. package/build-types/api.d.ts.map +1 -1
  39. package/build-types/index.d.ts +1 -1
  40. package/build-types/index.d.ts.map +1 -1
  41. package/build-types/store/actions.d.ts +5 -27
  42. package/build-types/store/actions.d.ts.map +1 -1
  43. package/build-types/store/constants.d.ts +2 -5
  44. package/build-types/store/constants.d.ts.map +1 -1
  45. package/build-types/store/index.d.ts.map +1 -1
  46. package/build-types/store/reducer.d.ts +21 -11
  47. package/build-types/store/reducer.d.ts.map +1 -1
  48. package/build-types/store/selectors.d.ts +2 -1
  49. package/build-types/store/selectors.d.ts.map +1 -1
  50. package/build-types/store/types.d.ts +18 -0
  51. package/build-types/store/types.d.ts.map +1 -0
  52. package/build-types/types.d.ts +14 -24
  53. package/build-types/types.d.ts.map +1 -1
  54. package/package.json +8 -10
  55. package/src/api.ts +43 -123
  56. package/src/index.ts +0 -1
  57. package/src/store/actions.ts +61 -46
  58. package/src/store/constants.ts +4 -5
  59. package/src/store/index.ts +2 -34
  60. package/src/store/reducer.ts +27 -33
  61. package/src/store/selectors.ts +3 -7
  62. package/src/store/tests/actions.test.ts +100 -244
  63. package/src/store/tests/reducer.test.ts +0 -451
  64. package/src/store/tests/selectors.test.ts +1 -1
  65. package/src/store/types.ts +19 -0
  66. package/src/tests/api.test.ts +112 -158
  67. package/src/types.ts +14 -26
  68. package/build/api.js.map +0 -7
  69. package/build/store/actions.js.map +0 -7
  70. package/build/store/constants.js.map +0 -7
  71. package/build/store/index.js.map +0 -7
  72. package/build/store/reducer.js.map +0 -7
  73. package/build/store/resolvers.js +0 -107
  74. package/build/store/resolvers.js.map +0 -7
  75. package/build/store/selectors.js.map +0 -7
  76. package/build/types.js.map +0 -7
  77. package/build-module/store/resolvers.js +0 -84
  78. package/build-module/store/resolvers.js.map +0 -7
  79. package/build-types/store/resolvers.d.ts +0 -47
  80. package/build-types/store/resolvers.d.ts.map +0 -1
  81. package/src/store/resolvers.ts +0 -151
  82. package/src/store/tests/resolvers.test.ts +0 -642
  83. /package/build/{validation.js.map → validation.cjs.map} +0 -0
@@ -2,27 +2,18 @@
2
2
  * Tests for store actions.
3
3
  */
4
4
 
5
- /**
6
- * WordPress dependencies
7
- */
8
- import { resolveSelect } from '@wordpress/data';
9
-
10
5
  /**
11
6
  * Internal dependencies
12
7
  */
13
8
  import {
14
- receiveAbilities,
15
9
  registerAbility,
16
10
  unregisterAbility,
17
- receiveCategories,
18
11
  registerAbilityCategory,
19
12
  unregisterAbilityCategory,
20
13
  } from '../actions';
21
14
  import {
22
- RECEIVE_ABILITIES,
23
15
  REGISTER_ABILITY,
24
16
  UNREGISTER_ABILITY,
25
- RECEIVE_CATEGORIES,
26
17
  REGISTER_ABILITY_CATEGORY,
27
18
  UNREGISTER_ABILITY_CATEGORY,
28
19
  } from '../constants';
@@ -32,52 +23,7 @@ import type {
32
23
  AbilityCategoryArgs,
33
24
  } from '../../types';
34
25
 
35
- // Mock the WordPress data store
36
- jest.mock( '@wordpress/data', () => ( {
37
- resolveSelect: jest.fn(),
38
- } ) );
39
-
40
26
  describe( 'Store Actions', () => {
41
- describe( 'receiveAbilities', () => {
42
- it( 'should create an action to receive abilities', () => {
43
- const abilities: Ability[] = [
44
- {
45
- name: 'test/ability1',
46
- label: 'Test Ability 1',
47
- description: 'First test ability',
48
- category: 'test-category',
49
- input_schema: { type: 'object' },
50
- output_schema: { type: 'object' },
51
- },
52
- {
53
- name: 'test/ability2',
54
- label: 'Test Ability 2',
55
- description: 'Second test ability',
56
- category: 'test-category',
57
- input_schema: { type: 'object' },
58
- output_schema: { type: 'object' },
59
- },
60
- ];
61
-
62
- const action = receiveAbilities( abilities );
63
-
64
- expect( action ).toEqual( {
65
- type: RECEIVE_ABILITIES,
66
- abilities,
67
- } );
68
- } );
69
-
70
- it( 'should handle empty abilities array', () => {
71
- const abilities: Ability[] = [];
72
- const action = receiveAbilities( abilities );
73
-
74
- expect( action ).toEqual( {
75
- type: RECEIVE_ABILITIES,
76
- abilities: [],
77
- } );
78
- } );
79
- } );
80
-
81
27
  describe( 'registerAbility', () => {
82
28
  let mockSelect: any;
83
29
  let mockDispatch: jest.Mock;
@@ -119,16 +65,9 @@ describe( 'Store Actions', () => {
119
65
  } ),
120
66
  };
121
67
  mockDispatch = jest.fn();
122
-
123
- // Mock resolveSelect to return categories
124
- ( resolveSelect as jest.Mock ).mockReturnValue( {
125
- getAbilityCategories: jest
126
- .fn()
127
- .mockResolvedValue( defaultCategories ),
128
- } );
129
68
  } );
130
69
 
131
- it( 'should register a valid client ability', async () => {
70
+ it( 'should register a valid client ability', () => {
132
71
  const ability: Ability = {
133
72
  name: 'test/ability',
134
73
  label: 'Test Ability',
@@ -150,15 +89,18 @@ describe( 'Store Actions', () => {
150
89
  };
151
90
 
152
91
  const action = registerAbility( ability );
153
- await action( { select: mockSelect, dispatch: mockDispatch } );
92
+ action( { select: mockSelect, dispatch: mockDispatch } );
154
93
 
155
94
  expect( mockDispatch ).toHaveBeenCalledWith( {
156
95
  type: REGISTER_ABILITY,
157
- ability,
96
+ ability: {
97
+ ...ability,
98
+ meta: { annotations: { clientRegistered: true } },
99
+ },
158
100
  } );
159
101
  } );
160
102
 
161
- it( 'should register server-side abilities', async () => {
103
+ it( 'should register server-side abilities', () => {
162
104
  const ability: Ability = {
163
105
  name: 'test/server-ability',
164
106
  label: 'Server Ability',
@@ -169,15 +111,18 @@ describe( 'Store Actions', () => {
169
111
  };
170
112
 
171
113
  const action = registerAbility( ability );
172
- await action( { select: mockSelect, dispatch: mockDispatch } );
114
+ action( { select: mockSelect, dispatch: mockDispatch } );
173
115
 
174
116
  expect( mockDispatch ).toHaveBeenCalledWith( {
175
117
  type: REGISTER_ABILITY,
176
- ability,
118
+ ability: {
119
+ ...ability,
120
+ meta: { annotations: { clientRegistered: true } },
121
+ },
177
122
  } );
178
123
  } );
179
124
 
180
- it( 'should validate and reject ability without name', async () => {
125
+ it( 'should validate and reject ability without name', () => {
181
126
  const ability: Ability = {
182
127
  name: '',
183
128
  label: 'Test Ability',
@@ -188,13 +133,13 @@ describe( 'Store Actions', () => {
188
133
 
189
134
  const action = registerAbility( ability );
190
135
 
191
- await expect(
136
+ expect( () =>
192
137
  action( { select: mockSelect, dispatch: mockDispatch } )
193
- ).rejects.toThrow( 'Ability name is required' );
138
+ ).toThrow( 'Ability name is required' );
194
139
  expect( mockDispatch ).not.toHaveBeenCalled();
195
140
  } );
196
141
 
197
- it( 'should validate and reject ability with invalid name format', async () => {
142
+ it( 'should validate and reject ability with invalid name format', () => {
198
143
  const testCases = [
199
144
  'invalid', // No namespace
200
145
  'my-plugin/feature/action', // Multiple slashes
@@ -215,9 +160,9 @@ describe( 'Store Actions', () => {
215
160
 
216
161
  const action = registerAbility( ability );
217
162
 
218
- await expect(
163
+ expect( () =>
219
164
  action( { select: mockSelect, dispatch: mockDispatch } )
220
- ).rejects.toThrow(
165
+ ).toThrow(
221
166
  'Ability name must be a string containing a namespace prefix'
222
167
  );
223
168
  expect( mockDispatch ).not.toHaveBeenCalled();
@@ -225,7 +170,7 @@ describe( 'Store Actions', () => {
225
170
  }
226
171
  } );
227
172
 
228
- it( 'should validate and reject ability without label', async () => {
173
+ it( 'should validate and reject ability without label', () => {
229
174
  const ability: Ability = {
230
175
  name: 'test/ability',
231
176
  label: '',
@@ -236,13 +181,13 @@ describe( 'Store Actions', () => {
236
181
 
237
182
  const action = registerAbility( ability );
238
183
 
239
- await expect(
184
+ expect( () =>
240
185
  action( { select: mockSelect, dispatch: mockDispatch } )
241
- ).rejects.toThrow( 'Ability "test/ability" must have a label' );
186
+ ).toThrow( 'Ability "test/ability" must have a label' );
242
187
  expect( mockDispatch ).not.toHaveBeenCalled();
243
188
  } );
244
189
 
245
- it( 'should validate and reject ability without description', async () => {
190
+ it( 'should validate and reject ability without description', () => {
246
191
  const ability: Ability = {
247
192
  name: 'test/ability',
248
193
  label: 'Test Ability',
@@ -253,15 +198,13 @@ describe( 'Store Actions', () => {
253
198
 
254
199
  const action = registerAbility( ability );
255
200
 
256
- await expect(
201
+ expect( () =>
257
202
  action( { select: mockSelect, dispatch: mockDispatch } )
258
- ).rejects.toThrow(
259
- 'Ability "test/ability" must have a description'
260
- );
203
+ ).toThrow( 'Ability "test/ability" must have a description' );
261
204
  expect( mockDispatch ).not.toHaveBeenCalled();
262
205
  } );
263
206
 
264
- it( 'should validate and reject ability without category', async () => {
207
+ it( 'should validate and reject ability without category', () => {
265
208
  const ability: Ability = {
266
209
  name: 'test/ability',
267
210
  label: 'Test Ability',
@@ -272,13 +215,13 @@ describe( 'Store Actions', () => {
272
215
 
273
216
  const action = registerAbility( ability );
274
217
 
275
- await expect(
218
+ expect( () =>
276
219
  action( { select: mockSelect, dispatch: mockDispatch } )
277
- ).rejects.toThrow( 'Ability "test/ability" must have a category' );
220
+ ).toThrow( 'Ability "test/ability" must have a category' );
278
221
  expect( mockDispatch ).not.toHaveBeenCalled();
279
222
  } );
280
223
 
281
- it( 'should validate and reject ability with invalid category format', async () => {
224
+ it( 'should validate and reject ability with invalid category format', () => {
282
225
  const testCases = [
283
226
  'Data-Retrieval', // Uppercase letters
284
227
  'data_retrieval', // Underscores not allowed
@@ -300,9 +243,9 @@ describe( 'Store Actions', () => {
300
243
 
301
244
  const action = registerAbility( ability );
302
245
 
303
- await expect(
246
+ expect( () =>
304
247
  action( { select: mockSelect, dispatch: mockDispatch } )
305
- ).rejects.toThrow(
248
+ ).toThrow(
306
249
  'Ability "test/ability" has an invalid category. Category must be lowercase alphanumeric with dashes only'
307
250
  );
308
251
  expect( mockDispatch ).not.toHaveBeenCalled();
@@ -310,7 +253,7 @@ describe( 'Store Actions', () => {
310
253
  }
311
254
  } );
312
255
 
313
- it( 'should accept ability with valid category format', async () => {
256
+ it( 'should accept ability with valid category format', () => {
314
257
  const validCategories = [
315
258
  'data-retrieval',
316
259
  'user-management',
@@ -345,30 +288,28 @@ describe( 'Store Actions', () => {
345
288
  },
346
289
  ];
347
290
 
348
- // Mock both select and resolveSelect
291
+ // Mock select to return categories
349
292
  mockSelect.getAbilityCategories.mockReturnValue(
350
293
  categoriesForTest
351
294
  );
352
- ( resolveSelect as jest.Mock ).mockReturnValue( {
353
- getAbilityCategories: jest
354
- .fn()
355
- .mockResolvedValue( categoriesForTest ),
356
- } );
357
295
 
358
296
  mockSelect.getAbility.mockReturnValue( null );
359
297
  mockDispatch.mockClear();
360
298
 
361
299
  const action = registerAbility( ability );
362
- await action( { select: mockSelect, dispatch: mockDispatch } );
300
+ action( { select: mockSelect, dispatch: mockDispatch } );
363
301
 
364
302
  expect( mockDispatch ).toHaveBeenCalledWith( {
365
303
  type: REGISTER_ABILITY,
366
- ability,
304
+ ability: {
305
+ ...ability,
306
+ meta: { annotations: { clientRegistered: true } },
307
+ },
367
308
  } );
368
309
  }
369
310
  } );
370
311
 
371
- it( 'should validate and reject ability with non-existent category', async () => {
312
+ it( 'should validate and reject ability with non-existent category', () => {
372
313
  mockSelect.getAbilityCategories.mockReturnValue( [
373
314
  {
374
315
  slug: 'test-category',
@@ -392,15 +333,15 @@ describe( 'Store Actions', () => {
392
333
 
393
334
  const action = registerAbility( ability );
394
335
 
395
- await expect(
336
+ expect( () =>
396
337
  action( { select: mockSelect, dispatch: mockDispatch } )
397
- ).rejects.toThrow(
338
+ ).toThrow(
398
339
  'Ability "test/ability" references non-existent category "non-existent-category". Please register the category first.'
399
340
  );
400
341
  expect( mockDispatch ).not.toHaveBeenCalled();
401
342
  } );
402
343
 
403
- it( 'should accept ability with existing category', async () => {
344
+ it( 'should accept ability with existing category', () => {
404
345
  const categoriesForTest = [
405
346
  {
406
347
  slug: 'test-category',
@@ -417,11 +358,6 @@ describe( 'Store Actions', () => {
417
358
  mockSelect.getAbilityCategories.mockReturnValue(
418
359
  categoriesForTest
419
360
  );
420
- ( resolveSelect as jest.Mock ).mockReturnValue( {
421
- getAbilityCategories: jest
422
- .fn()
423
- .mockResolvedValue( categoriesForTest ),
424
- } );
425
361
 
426
362
  const ability: Ability = {
427
363
  name: 'test/ability',
@@ -432,17 +368,18 @@ describe( 'Store Actions', () => {
432
368
  };
433
369
 
434
370
  const action = registerAbility( ability );
435
- await action( { select: mockSelect, dispatch: mockDispatch } );
371
+ action( { select: mockSelect, dispatch: mockDispatch } );
436
372
 
437
- // resolveSelect should have been called to load categories
438
- expect( resolveSelect ).toHaveBeenCalledWith( 'core/abilities' );
439
373
  expect( mockDispatch ).toHaveBeenCalledWith( {
440
374
  type: REGISTER_ABILITY,
441
- ability,
375
+ ability: {
376
+ ...ability,
377
+ meta: { annotations: { clientRegistered: true } },
378
+ },
442
379
  } );
443
380
  } );
444
381
 
445
- it( 'should validate and reject ability with invalid callback', async () => {
382
+ it( 'should validate and reject ability with invalid callback', () => {
446
383
  const ability: Ability = {
447
384
  name: 'test/ability',
448
385
  label: 'Test Ability',
@@ -453,15 +390,15 @@ describe( 'Store Actions', () => {
453
390
 
454
391
  const action = registerAbility( ability );
455
392
 
456
- await expect(
393
+ expect( () =>
457
394
  action( { select: mockSelect, dispatch: mockDispatch } )
458
- ).rejects.toThrow(
395
+ ).toThrow(
459
396
  'Ability "test/ability" has an invalid callback. Callback must be a function'
460
397
  );
461
398
  expect( mockDispatch ).not.toHaveBeenCalled();
462
399
  } );
463
400
 
464
- it( 'should validate and reject already registered ability', async () => {
401
+ it( 'should validate and reject already registered ability', () => {
465
402
  const existingAbility: Ability = {
466
403
  name: 'test/ability',
467
404
  label: 'Existing Ability',
@@ -481,45 +418,11 @@ describe( 'Store Actions', () => {
481
418
 
482
419
  const action = registerAbility( ability );
483
420
 
484
- await expect(
421
+ expect( () =>
485
422
  action( { select: mockSelect, dispatch: mockDispatch } )
486
- ).rejects.toThrow( 'Ability "test/ability" is already registered' );
423
+ ).toThrow( 'Ability "test/ability" is already registered' );
487
424
  expect( mockDispatch ).not.toHaveBeenCalled();
488
425
  } );
489
-
490
- it( 'should load categories using resolveSelect before validation', async () => {
491
- const categories = [
492
- {
493
- slug: 'test-category',
494
- label: 'Test Category',
495
- description: 'Test category',
496
- },
497
- ];
498
-
499
- // Mock resolveSelect to return categories directly
500
- ( resolveSelect as jest.Mock ).mockReturnValue( {
501
- getAbilityCategories: jest.fn().mockResolvedValue( categories ),
502
- } );
503
-
504
- const ability: Ability = {
505
- name: 'test/ability',
506
- label: 'Test Ability',
507
- description: 'Test description',
508
- category: 'test-category',
509
- callback: jest.fn(),
510
- };
511
-
512
- const action = registerAbility( ability );
513
- await action( { select: mockSelect, dispatch: mockDispatch } );
514
-
515
- // Should have called resolveSelect to load categories
516
- expect( resolveSelect ).toHaveBeenCalledWith( 'core/abilities' );
517
- // Should have successfully registered
518
- expect( mockDispatch ).toHaveBeenCalledWith( {
519
- type: REGISTER_ABILITY,
520
- ability,
521
- } );
522
- } );
523
426
  } );
524
427
 
525
428
  describe( 'unregisterAbility', () => {
@@ -544,40 +447,6 @@ describe( 'Store Actions', () => {
544
447
  } );
545
448
  } );
546
449
 
547
- describe( 'receiveCategories', () => {
548
- it( 'should create an action to receive categories', () => {
549
- const categories: AbilityCategory[] = [
550
- {
551
- slug: 'data-retrieval',
552
- label: 'Data Retrieval',
553
- description: 'Abilities that retrieve data',
554
- },
555
- {
556
- slug: 'user-management',
557
- label: 'User Management',
558
- description: 'Abilities for managing users',
559
- },
560
- ];
561
-
562
- const action = receiveCategories( categories );
563
-
564
- expect( action ).toEqual( {
565
- type: RECEIVE_CATEGORIES,
566
- categories,
567
- } );
568
- } );
569
-
570
- it( 'should handle empty categories array', () => {
571
- const categories: AbilityCategory[] = [];
572
- const action = receiveCategories( categories );
573
-
574
- expect( action ).toEqual( {
575
- type: RECEIVE_CATEGORIES,
576
- categories: [],
577
- } );
578
- } );
579
- } );
580
-
581
450
  describe( 'registerAbilityCategory', () => {
582
451
  let mockSelect: any;
583
452
  let mockDispatch: jest.Mock;
@@ -589,14 +458,9 @@ describe( 'Store Actions', () => {
589
458
  getAbilityCategories: jest.fn().mockReturnValue( [] ),
590
459
  };
591
460
  mockDispatch = jest.fn();
592
-
593
- // Mock resolveSelect to return a mock that resolves the getAbilityCategories call
594
- ( resolveSelect as jest.Mock ).mockReturnValue( {
595
- getAbilityCategories: jest.fn().mockResolvedValue( undefined ),
596
- } );
597
461
  } );
598
462
 
599
- it( 'should register a valid category', async () => {
463
+ it( 'should register a valid category', () => {
600
464
  const slug = 'test-category';
601
465
  const args: AbilityCategoryArgs = {
602
466
  label: 'Test Category',
@@ -604,7 +468,7 @@ describe( 'Store Actions', () => {
604
468
  };
605
469
 
606
470
  const action = registerAbilityCategory( slug, args );
607
- await action( { select: mockSelect, dispatch: mockDispatch } );
471
+ action( { select: mockSelect, dispatch: mockDispatch } );
608
472
 
609
473
  expect( mockDispatch ).toHaveBeenCalledWith( {
610
474
  type: REGISTER_ABILITY_CATEGORY,
@@ -612,24 +476,25 @@ describe( 'Store Actions', () => {
612
476
  slug,
613
477
  label: args.label,
614
478
  description: args.description,
615
- meta: {
616
- _clientRegistered: true,
617
- },
479
+ meta: { annotations: { clientRegistered: true } },
618
480
  },
619
481
  } );
620
482
  } );
621
483
 
622
- it( 'should register a category with meta', async () => {
484
+ it( 'should register a category with meta and filter to only annotations', () => {
623
485
  const slug = 'test-category';
624
486
  const args: AbilityCategoryArgs = {
625
487
  label: 'Test Category',
626
488
  description: 'A test category',
627
- meta: { foo: 'bar', nested: { key: 'value' } },
489
+ meta: {
490
+ annotations: { serverRegistered: true },
491
+ },
628
492
  };
629
493
 
630
494
  const action = registerAbilityCategory( slug, args );
631
- await action( { select: mockSelect, dispatch: mockDispatch } );
495
+ action( { select: mockSelect, dispatch: mockDispatch } );
632
496
 
497
+ // Should only keep annotations, not add clientRegistered since serverRegistered is true
633
498
  expect( mockDispatch ).toHaveBeenCalledWith( {
634
499
  type: REGISTER_ABILITY_CATEGORY,
635
500
  category: {
@@ -637,14 +502,13 @@ describe( 'Store Actions', () => {
637
502
  label: args.label,
638
503
  description: args.description,
639
504
  meta: {
640
- ...args.meta,
641
- _clientRegistered: true,
505
+ annotations: { serverRegistered: true },
642
506
  },
643
507
  },
644
508
  } );
645
509
  } );
646
510
 
647
- it( 'should validate and reject empty slug', async () => {
511
+ it( 'should validate and reject empty slug', () => {
648
512
  const args: AbilityCategoryArgs = {
649
513
  label: 'Test',
650
514
  description: 'Test',
@@ -652,13 +516,13 @@ describe( 'Store Actions', () => {
652
516
 
653
517
  const action = registerAbilityCategory( '', args );
654
518
 
655
- await expect(
519
+ expect( () =>
656
520
  action( { select: mockSelect, dispatch: mockDispatch } )
657
- ).rejects.toThrow( 'Category slug is required' );
521
+ ).toThrow( 'Category slug is required' );
658
522
  expect( mockDispatch ).not.toHaveBeenCalled();
659
523
  } );
660
524
 
661
- it( 'should validate and reject invalid slug formats', async () => {
525
+ it( 'should validate and reject invalid slug formats', () => {
662
526
  const testCases = [
663
527
  'Data-Retrieval', // Uppercase
664
528
  'data_retrieval', // Underscores
@@ -679,9 +543,9 @@ describe( 'Store Actions', () => {
679
543
  for ( const invalidSlug of testCases ) {
680
544
  const action = registerAbilityCategory( invalidSlug, args );
681
545
 
682
- await expect(
546
+ expect( () =>
683
547
  action( { select: mockSelect, dispatch: mockDispatch } )
684
- ).rejects.toThrow(
548
+ ).toThrow(
685
549
  'Category slug must contain only lowercase alphanumeric characters and dashes'
686
550
  );
687
551
  expect( mockDispatch ).not.toHaveBeenCalled();
@@ -689,7 +553,7 @@ describe( 'Store Actions', () => {
689
553
  }
690
554
  } );
691
555
 
692
- it( 'should accept valid slug formats', async () => {
556
+ it( 'should accept valid slug formats', () => {
693
557
  const validSlugs = [
694
558
  'data-retrieval',
695
559
  'user-management',
@@ -710,7 +574,7 @@ describe( 'Store Actions', () => {
710
574
  mockDispatch.mockClear();
711
575
 
712
576
  const action = registerAbilityCategory( validSlug, args );
713
- await action( { select: mockSelect, dispatch: mockDispatch } );
577
+ action( { select: mockSelect, dispatch: mockDispatch } );
714
578
 
715
579
  expect( mockDispatch ).toHaveBeenCalledWith( {
716
580
  type: REGISTER_ABILITY_CATEGORY,
@@ -718,15 +582,13 @@ describe( 'Store Actions', () => {
718
582
  slug: validSlug,
719
583
  label: args.label,
720
584
  description: args.description,
721
- meta: {
722
- _clientRegistered: true,
723
- },
585
+ meta: { annotations: { clientRegistered: true } },
724
586
  },
725
587
  } );
726
588
  }
727
589
  } );
728
590
 
729
- it( 'should validate and reject missing label', async () => {
591
+ it( 'should validate and reject missing label', () => {
730
592
  const slug = 'test-category';
731
593
  const args = {
732
594
  label: '',
@@ -735,15 +597,15 @@ describe( 'Store Actions', () => {
735
597
 
736
598
  const action = registerAbilityCategory( slug, args );
737
599
 
738
- await expect(
600
+ expect( () =>
739
601
  action( { select: mockSelect, dispatch: mockDispatch } )
740
- ).rejects.toThrow(
602
+ ).toThrow(
741
603
  'The category properties must contain a `label` string.'
742
604
  );
743
605
  expect( mockDispatch ).not.toHaveBeenCalled();
744
606
  } );
745
607
 
746
- it( 'should validate and reject non-string label', async () => {
608
+ it( 'should validate and reject non-string label', () => {
747
609
  const slug = 'test-category';
748
610
  const args = {
749
611
  label: 123 as any,
@@ -752,15 +614,15 @@ describe( 'Store Actions', () => {
752
614
 
753
615
  const action = registerAbilityCategory( slug, args );
754
616
 
755
- await expect(
617
+ expect( () =>
756
618
  action( { select: mockSelect, dispatch: mockDispatch } )
757
- ).rejects.toThrow(
619
+ ).toThrow(
758
620
  'The category properties must contain a `label` string.'
759
621
  );
760
622
  expect( mockDispatch ).not.toHaveBeenCalled();
761
623
  } );
762
624
 
763
- it( 'should validate and reject missing description', async () => {
625
+ it( 'should validate and reject missing description', () => {
764
626
  const slug = 'test-category';
765
627
  const args = {
766
628
  label: 'Test',
@@ -769,15 +631,15 @@ describe( 'Store Actions', () => {
769
631
 
770
632
  const action = registerAbilityCategory( slug, args );
771
633
 
772
- await expect(
634
+ expect( () =>
773
635
  action( { select: mockSelect, dispatch: mockDispatch } )
774
- ).rejects.toThrow(
636
+ ).toThrow(
775
637
  'The category properties must contain a `description` string.'
776
638
  );
777
639
  expect( mockDispatch ).not.toHaveBeenCalled();
778
640
  } );
779
641
 
780
- it( 'should validate and reject non-string description', async () => {
642
+ it( 'should validate and reject non-string description', () => {
781
643
  const slug = 'test-category';
782
644
  const args = {
783
645
  label: 'Test',
@@ -786,15 +648,15 @@ describe( 'Store Actions', () => {
786
648
 
787
649
  const action = registerAbilityCategory( slug, args );
788
650
 
789
- await expect(
651
+ expect( () =>
790
652
  action( { select: mockSelect, dispatch: mockDispatch } )
791
- ).rejects.toThrow(
653
+ ).toThrow(
792
654
  'The category properties must contain a `description` string.'
793
655
  );
794
656
  expect( mockDispatch ).not.toHaveBeenCalled();
795
657
  } );
796
658
 
797
- it( 'should validate and reject non-object meta', async () => {
659
+ it( 'should validate and reject non-object meta', () => {
798
660
  const slug = 'test-category';
799
661
  const args = {
800
662
  label: 'Test',
@@ -804,15 +666,15 @@ describe( 'Store Actions', () => {
804
666
 
805
667
  const action = registerAbilityCategory( slug, args );
806
668
 
807
- await expect(
669
+ expect( () =>
808
670
  action( { select: mockSelect, dispatch: mockDispatch } )
809
- ).rejects.toThrow(
671
+ ).toThrow(
810
672
  'The category properties should provide a valid `meta` object.'
811
673
  );
812
674
  expect( mockDispatch ).not.toHaveBeenCalled();
813
675
  } );
814
676
 
815
- it( 'should validate and reject array as meta', async () => {
677
+ it( 'should validate and reject array as meta', () => {
816
678
  const slug = 'test-category';
817
679
  const args = {
818
680
  label: 'Test',
@@ -822,15 +684,15 @@ describe( 'Store Actions', () => {
822
684
 
823
685
  const action = registerAbilityCategory( slug, args );
824
686
 
825
- await expect(
687
+ expect( () =>
826
688
  action( { select: mockSelect, dispatch: mockDispatch } )
827
- ).rejects.toThrow(
689
+ ).toThrow(
828
690
  'The category properties should provide a valid `meta` object.'
829
691
  );
830
692
  expect( mockDispatch ).not.toHaveBeenCalled();
831
693
  } );
832
694
 
833
- it( 'should validate and reject already registered category', async () => {
695
+ it( 'should validate and reject already registered category', () => {
834
696
  const existingCategory: AbilityCategory = {
835
697
  slug: 'test-category',
836
698
  label: 'Existing Category',
@@ -846,15 +708,13 @@ describe( 'Store Actions', () => {
846
708
 
847
709
  const action = registerAbilityCategory( 'test-category', args );
848
710
 
849
- await expect(
711
+ expect( () =>
850
712
  action( { select: mockSelect, dispatch: mockDispatch } )
851
- ).rejects.toThrow(
852
- 'Category "test-category" is already registered.'
853
- );
713
+ ).toThrow( 'Category "test-category" is already registered.' );
854
714
  expect( mockDispatch ).not.toHaveBeenCalled();
855
715
  } );
856
716
 
857
- it( 'should allow registering ability after registering category', async () => {
717
+ it( 'should allow registering ability after registering category', () => {
858
718
  // First register a category
859
719
  const categorySlug = 'new-category';
860
720
  const categoryArgs: AbilityCategoryArgs = {
@@ -866,7 +726,7 @@ describe( 'Store Actions', () => {
866
726
  categorySlug,
867
727
  categoryArgs
868
728
  );
869
- await categoryAction( {
729
+ categoryAction( {
870
730
  select: mockSelect,
871
731
  dispatch: mockDispatch,
872
732
  } );
@@ -878,9 +738,7 @@ describe( 'Store Actions', () => {
878
738
  slug: categorySlug,
879
739
  label: categoryArgs.label,
880
740
  description: categoryArgs.description,
881
- meta: {
882
- _clientRegistered: true,
883
- },
741
+ meta: { annotations: { clientRegistered: true } },
884
742
  },
885
743
  } );
886
744
 
@@ -895,11 +753,6 @@ describe( 'Store Actions', () => {
895
753
  mockSelect.getAbilityCategories = jest
896
754
  .fn()
897
755
  .mockReturnValue( categoriesWithNew );
898
- ( resolveSelect as jest.Mock ).mockReturnValue( {
899
- getAbilityCategories: jest
900
- .fn()
901
- .mockResolvedValue( categoriesWithNew ),
902
- } );
903
756
  mockSelect.getAbility = jest.fn().mockReturnValue( null );
904
757
  mockDispatch.mockClear();
905
758
 
@@ -913,7 +766,7 @@ describe( 'Store Actions', () => {
913
766
  };
914
767
 
915
768
  const abilityAction = registerAbility( ability );
916
- await abilityAction( {
769
+ abilityAction( {
917
770
  select: mockSelect,
918
771
  dispatch: mockDispatch,
919
772
  } );
@@ -921,7 +774,10 @@ describe( 'Store Actions', () => {
921
774
  // Should successfully register with the new category
922
775
  expect( mockDispatch ).toHaveBeenCalledWith( {
923
776
  type: REGISTER_ABILITY,
924
- ability,
777
+ ability: {
778
+ ...ability,
779
+ meta: { annotations: { clientRegistered: true } },
780
+ },
925
781
  } );
926
782
  } );
927
783
  } );