@wordpress/abilities 0.2.0 → 0.2.1-next.738bb1424.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/README.md +32 -40
- package/build/{api.js → api.cjs} +22 -69
- package/build/api.cjs.map +7 -0
- package/build/{index.js → index.cjs} +4 -4
- package/build/{index.js.map → index.cjs.map} +2 -2
- package/build/store/{actions.js → actions.cjs} +43 -33
- package/build/store/actions.cjs.map +7 -0
- package/build/store/{constants.js → constants.cjs} +7 -16
- package/build/store/constants.cjs.map +7 -0
- package/build/store/{index.js → index.cjs} +6 -32
- package/build/store/index.cjs.map +7 -0
- package/build/store/{reducer.js → reducer.cjs} +4 -24
- package/build/store/reducer.cjs.map +7 -0
- package/build/store/{selectors.js → selectors.cjs} +2 -2
- package/build/store/selectors.cjs.map +7 -0
- package/build/store/types.cjs +19 -0
- package/build/store/types.cjs.map +7 -0
- package/build/{types.js → types.cjs} +1 -1
- package/build/types.cjs.map +7 -0
- package/build/{validation.js → validation.cjs} +3 -3
- package/build-module/api.js +22 -59
- package/build-module/api.js.map +2 -2
- package/build-module/index.js +3 -3
- package/build-module/index.js.map +2 -2
- package/build-module/store/actions.js +44 -33
- package/build-module/store/actions.js.map +2 -2
- package/build-module/store/constants.js +4 -10
- package/build-module/store/constants.js.map +2 -2
- package/build-module/store/index.js +6 -37
- package/build-module/store/index.js.map +2 -2
- package/build-module/store/reducer.js +3 -25
- package/build-module/store/reducer.js.map +2 -2
- package/build-module/store/selectors.js +1 -1
- package/build-module/store/selectors.js.map +2 -2
- package/build-module/store/types.js +1 -0
- package/build-module/store/types.js.map +7 -0
- package/build-types/api.d.ts +16 -23
- package/build-types/api.d.ts.map +1 -1
- package/build-types/index.d.ts +1 -1
- package/build-types/index.d.ts.map +1 -1
- package/build-types/store/actions.d.ts +5 -27
- package/build-types/store/actions.d.ts.map +1 -1
- package/build-types/store/constants.d.ts +2 -5
- package/build-types/store/constants.d.ts.map +1 -1
- package/build-types/store/index.d.ts +1 -1
- package/build-types/store/index.d.ts.map +1 -1
- package/build-types/store/reducer.d.ts +21 -11
- package/build-types/store/reducer.d.ts.map +1 -1
- package/build-types/store/selectors.d.ts +2 -1
- package/build-types/store/selectors.d.ts.map +1 -1
- package/build-types/store/types.d.ts +18 -0
- package/build-types/store/types.d.ts.map +1 -0
- package/build-types/types.d.ts +14 -24
- package/build-types/types.d.ts.map +1 -1
- package/package.json +8 -10
- package/src/api.ts +43 -123
- package/src/index.ts +0 -1
- package/src/store/actions.ts +61 -46
- package/src/store/constants.ts +4 -5
- package/src/store/index.ts +2 -34
- package/src/store/reducer.ts +27 -33
- package/src/store/selectors.ts +3 -7
- package/src/store/tests/actions.test.ts +100 -244
- package/src/store/tests/reducer.test.ts +0 -451
- package/src/store/tests/selectors.test.ts +1 -1
- package/src/store/types.ts +19 -0
- package/src/tests/api.test.ts +112 -158
- package/src/types.ts +14 -26
- package/build/api.js.map +0 -7
- package/build/store/actions.js.map +0 -7
- package/build/store/constants.js.map +0 -7
- package/build/store/index.js.map +0 -7
- package/build/store/reducer.js.map +0 -7
- package/build/store/resolvers.js +0 -107
- package/build/store/resolvers.js.map +0 -7
- package/build/store/selectors.js.map +0 -7
- package/build/types.js.map +0 -7
- package/build-module/store/resolvers.js +0 -84
- package/build-module/store/resolvers.js.map +0 -7
- package/build-types/store/resolvers.d.ts +0 -47
- package/build-types/store/resolvers.d.ts.map +0 -1
- package/src/store/resolvers.ts +0 -151
- package/src/store/tests/resolvers.test.ts +0 -642
- /package/build/{validation.js.map → validation.cjs.map} +0 -0
|
@@ -7,10 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import reducer from '../reducer';
|
|
9
9
|
import {
|
|
10
|
-
RECEIVE_ABILITIES,
|
|
11
10
|
REGISTER_ABILITY,
|
|
12
11
|
UNREGISTER_ABILITY,
|
|
13
|
-
RECEIVE_CATEGORIES,
|
|
14
12
|
REGISTER_ABILITY_CATEGORY,
|
|
15
13
|
UNREGISTER_ABILITY_CATEGORY,
|
|
16
14
|
} from '../constants';
|
|
@@ -19,158 +17,6 @@ describe( 'Store Reducer', () => {
|
|
|
19
17
|
describe( 'abilitiesByName', () => {
|
|
20
18
|
const defaultState = {};
|
|
21
19
|
|
|
22
|
-
describe( 'RECEIVE_ABILITIES', () => {
|
|
23
|
-
it( 'should add abilities to the state', () => {
|
|
24
|
-
const abilities = [
|
|
25
|
-
{
|
|
26
|
-
name: 'test/ability1',
|
|
27
|
-
label: 'Test Ability 1',
|
|
28
|
-
description: 'First test ability',
|
|
29
|
-
input_schema: { type: 'object' },
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
name: 'test/ability2',
|
|
33
|
-
label: 'Test Ability 2',
|
|
34
|
-
description: 'Second test ability',
|
|
35
|
-
output_schema: { type: 'object' },
|
|
36
|
-
},
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
const action = {
|
|
40
|
-
type: RECEIVE_ABILITIES,
|
|
41
|
-
abilities,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const state = reducer(
|
|
45
|
-
{ abilitiesByName: defaultState },
|
|
46
|
-
action
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
expect( state.abilitiesByName ).toHaveProperty(
|
|
50
|
-
'test/ability1'
|
|
51
|
-
);
|
|
52
|
-
expect( state.abilitiesByName ).toHaveProperty(
|
|
53
|
-
'test/ability2'
|
|
54
|
-
);
|
|
55
|
-
expect( state.abilitiesByName[ 'test/ability1' ].label ).toBe(
|
|
56
|
-
'Test Ability 1'
|
|
57
|
-
);
|
|
58
|
-
expect( state.abilitiesByName[ 'test/ability2' ].label ).toBe(
|
|
59
|
-
'Test Ability 2'
|
|
60
|
-
);
|
|
61
|
-
} );
|
|
62
|
-
|
|
63
|
-
it( 'should filter out _links from server responses', () => {
|
|
64
|
-
const abilities = [
|
|
65
|
-
{
|
|
66
|
-
name: 'test/ability',
|
|
67
|
-
label: 'Test Ability',
|
|
68
|
-
description: 'Test ability with links',
|
|
69
|
-
_links: {
|
|
70
|
-
self: {
|
|
71
|
-
href: '/wp-abilities/v1/abilities/test/ability',
|
|
72
|
-
},
|
|
73
|
-
collection: { href: '/wp-abilities/v1/abilities' },
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
];
|
|
77
|
-
|
|
78
|
-
const action = {
|
|
79
|
-
type: RECEIVE_ABILITIES,
|
|
80
|
-
abilities,
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const state = reducer(
|
|
84
|
-
{ abilitiesByName: defaultState },
|
|
85
|
-
action
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
expect(
|
|
89
|
-
state.abilitiesByName[ 'test/ability' ]
|
|
90
|
-
).not.toHaveProperty( '_links' );
|
|
91
|
-
expect( state.abilitiesByName[ 'test/ability' ].name ).toBe(
|
|
92
|
-
'test/ability'
|
|
93
|
-
);
|
|
94
|
-
expect( state.abilitiesByName[ 'test/ability' ].label ).toBe(
|
|
95
|
-
'Test Ability'
|
|
96
|
-
);
|
|
97
|
-
} );
|
|
98
|
-
|
|
99
|
-
it( 'should filter out _embedded from server responses', () => {
|
|
100
|
-
const abilities = [
|
|
101
|
-
{
|
|
102
|
-
name: 'test/ability',
|
|
103
|
-
label: 'Test Ability',
|
|
104
|
-
description: 'Test ability with embedded',
|
|
105
|
-
_embedded: {
|
|
106
|
-
author: { id: 1, name: 'Admin' },
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
];
|
|
110
|
-
|
|
111
|
-
const action = {
|
|
112
|
-
type: RECEIVE_ABILITIES,
|
|
113
|
-
abilities,
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const state = reducer(
|
|
117
|
-
{ abilitiesByName: defaultState },
|
|
118
|
-
action
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
expect(
|
|
122
|
-
state.abilitiesByName[ 'test/ability' ]
|
|
123
|
-
).not.toHaveProperty( '_embedded' );
|
|
124
|
-
} );
|
|
125
|
-
|
|
126
|
-
it( 'should preserve all valid ability properties', () => {
|
|
127
|
-
const abilities = [
|
|
128
|
-
{
|
|
129
|
-
name: 'test/ability',
|
|
130
|
-
label: 'Test Ability',
|
|
131
|
-
description: 'Full test ability.',
|
|
132
|
-
input_schema: { type: 'object' },
|
|
133
|
-
output_schema: { type: 'object' },
|
|
134
|
-
meta: {
|
|
135
|
-
category: 'test',
|
|
136
|
-
},
|
|
137
|
-
callback: () => Promise.resolve( {} ),
|
|
138
|
-
permissionCallback: () => true,
|
|
139
|
-
// Extra properties that should be filtered out
|
|
140
|
-
_links: { self: { href: '/test' } },
|
|
141
|
-
_embedded: { test: 'value' },
|
|
142
|
-
extra_field: 'should be removed',
|
|
143
|
-
},
|
|
144
|
-
];
|
|
145
|
-
|
|
146
|
-
const action = {
|
|
147
|
-
type: RECEIVE_ABILITIES,
|
|
148
|
-
abilities,
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const state = reducer(
|
|
152
|
-
{ abilitiesByName: defaultState },
|
|
153
|
-
action
|
|
154
|
-
);
|
|
155
|
-
const ability = state.abilitiesByName[ 'test/ability' ];
|
|
156
|
-
|
|
157
|
-
// Should have valid properties
|
|
158
|
-
expect( ability.name ).toBe( 'test/ability' );
|
|
159
|
-
expect( ability.label ).toBe( 'Test Ability' );
|
|
160
|
-
expect( ability.description ).toBe( 'Full test ability.' );
|
|
161
|
-
expect( ability.input_schema ).toEqual( { type: 'object' } );
|
|
162
|
-
expect( ability.output_schema ).toEqual( { type: 'object' } );
|
|
163
|
-
expect( ability.meta ).toEqual( { category: 'test' } );
|
|
164
|
-
expect( ability.callback ).toBeDefined();
|
|
165
|
-
expect( ability.permissionCallback ).toBeDefined();
|
|
166
|
-
|
|
167
|
-
// Should NOT have invalid properties
|
|
168
|
-
expect( ability ).not.toHaveProperty( '_links' );
|
|
169
|
-
expect( ability ).not.toHaveProperty( '_embedded' );
|
|
170
|
-
expect( ability ).not.toHaveProperty( 'extra_field' );
|
|
171
|
-
} );
|
|
172
|
-
} );
|
|
173
|
-
|
|
174
20
|
describe( 'REGISTER_ABILITY', () => {
|
|
175
21
|
it( 'should add ability to the state', () => {
|
|
176
22
|
const ability = {
|
|
@@ -327,20 +173,6 @@ describe( 'Store Reducer', () => {
|
|
|
327
173
|
expect( state.abilitiesByName ).toEqual( initialState );
|
|
328
174
|
} );
|
|
329
175
|
|
|
330
|
-
it( 'should handle undefined abilities in RECEIVE_ABILITIES', () => {
|
|
331
|
-
const action = {
|
|
332
|
-
type: RECEIVE_ABILITIES,
|
|
333
|
-
abilities: undefined,
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
const state = reducer(
|
|
337
|
-
{ abilitiesByName: defaultState },
|
|
338
|
-
action
|
|
339
|
-
);
|
|
340
|
-
|
|
341
|
-
expect( state.abilitiesByName ).toEqual( defaultState );
|
|
342
|
-
} );
|
|
343
|
-
|
|
344
176
|
it( 'should handle undefined ability in REGISTER_ABILITY', () => {
|
|
345
177
|
const action = {
|
|
346
178
|
type: REGISTER_ABILITY,
|
|
@@ -354,295 +186,12 @@ describe( 'Store Reducer', () => {
|
|
|
354
186
|
|
|
355
187
|
expect( state.abilitiesByName ).toEqual( defaultState );
|
|
356
188
|
} );
|
|
357
|
-
|
|
358
|
-
it( 'should handle undefined properties gracefully', () => {
|
|
359
|
-
const abilities = [
|
|
360
|
-
{
|
|
361
|
-
name: 'test/minimal',
|
|
362
|
-
label: 'Minimal',
|
|
363
|
-
description:
|
|
364
|
-
'Minimal ability with undefined properties',
|
|
365
|
-
input_schema: undefined,
|
|
366
|
-
output_schema: undefined,
|
|
367
|
-
meta: undefined,
|
|
368
|
-
callback: undefined,
|
|
369
|
-
permissionCallback: undefined,
|
|
370
|
-
},
|
|
371
|
-
];
|
|
372
|
-
|
|
373
|
-
const action = {
|
|
374
|
-
type: RECEIVE_ABILITIES,
|
|
375
|
-
abilities,
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
const state = reducer(
|
|
379
|
-
{ abilitiesByName: defaultState },
|
|
380
|
-
action
|
|
381
|
-
);
|
|
382
|
-
const ability = state.abilitiesByName[ 'test/minimal' ];
|
|
383
|
-
|
|
384
|
-
expect( ability.name ).toBe( 'test/minimal' );
|
|
385
|
-
expect( ability.label ).toBe( 'Minimal' );
|
|
386
|
-
expect( ability.description ).toBe(
|
|
387
|
-
'Minimal ability with undefined properties'
|
|
388
|
-
);
|
|
389
|
-
// Undefined properties should not be present
|
|
390
|
-
expect( ability ).not.toHaveProperty( 'input_schema' );
|
|
391
|
-
expect( ability ).not.toHaveProperty( 'output_schema' );
|
|
392
|
-
expect( ability ).not.toHaveProperty( 'meta' );
|
|
393
|
-
expect( ability ).not.toHaveProperty( 'callback' );
|
|
394
|
-
expect( ability ).not.toHaveProperty( 'permissionCallback' );
|
|
395
|
-
} );
|
|
396
189
|
} );
|
|
397
190
|
} );
|
|
398
191
|
|
|
399
192
|
describe( 'categoriesBySlug', () => {
|
|
400
193
|
const defaultState = {};
|
|
401
194
|
|
|
402
|
-
describe( 'RECEIVE_CATEGORIES', () => {
|
|
403
|
-
it( 'should add categories to the state', () => {
|
|
404
|
-
const categories = [
|
|
405
|
-
{
|
|
406
|
-
slug: 'data-retrieval',
|
|
407
|
-
label: 'Data Retrieval',
|
|
408
|
-
description: 'Abilities that retrieve data',
|
|
409
|
-
},
|
|
410
|
-
{
|
|
411
|
-
slug: 'user-management',
|
|
412
|
-
label: 'User Management',
|
|
413
|
-
description: 'Abilities for managing users',
|
|
414
|
-
},
|
|
415
|
-
];
|
|
416
|
-
|
|
417
|
-
const action = {
|
|
418
|
-
type: RECEIVE_CATEGORIES,
|
|
419
|
-
categories,
|
|
420
|
-
};
|
|
421
|
-
|
|
422
|
-
const state = reducer(
|
|
423
|
-
{ categoriesBySlug: defaultState, abilitiesByName: {} },
|
|
424
|
-
action
|
|
425
|
-
);
|
|
426
|
-
|
|
427
|
-
expect( state.categoriesBySlug ).toHaveProperty(
|
|
428
|
-
'data-retrieval'
|
|
429
|
-
);
|
|
430
|
-
expect( state.categoriesBySlug ).toHaveProperty(
|
|
431
|
-
'user-management'
|
|
432
|
-
);
|
|
433
|
-
expect( state.categoriesBySlug[ 'data-retrieval' ].label ).toBe(
|
|
434
|
-
'Data Retrieval'
|
|
435
|
-
);
|
|
436
|
-
expect(
|
|
437
|
-
state.categoriesBySlug[ 'user-management' ].label
|
|
438
|
-
).toBe( 'User Management' );
|
|
439
|
-
} );
|
|
440
|
-
|
|
441
|
-
it( 'should filter out _links from server responses', () => {
|
|
442
|
-
const categories = [
|
|
443
|
-
{
|
|
444
|
-
slug: 'data-retrieval',
|
|
445
|
-
label: 'Data Retrieval',
|
|
446
|
-
description: 'Test category with links',
|
|
447
|
-
_links: {
|
|
448
|
-
self: {
|
|
449
|
-
href: '/wp-abilities/v1/categories/data-retrieval',
|
|
450
|
-
},
|
|
451
|
-
collection: {
|
|
452
|
-
href: '/wp-abilities/v1/categories',
|
|
453
|
-
},
|
|
454
|
-
},
|
|
455
|
-
},
|
|
456
|
-
];
|
|
457
|
-
|
|
458
|
-
const action = {
|
|
459
|
-
type: RECEIVE_CATEGORIES,
|
|
460
|
-
categories,
|
|
461
|
-
};
|
|
462
|
-
|
|
463
|
-
const state = reducer(
|
|
464
|
-
{ categoriesBySlug: defaultState, abilitiesByName: {} },
|
|
465
|
-
action
|
|
466
|
-
);
|
|
467
|
-
|
|
468
|
-
expect(
|
|
469
|
-
state.categoriesBySlug[ 'data-retrieval' ]
|
|
470
|
-
).not.toHaveProperty( '_links' );
|
|
471
|
-
expect( state.categoriesBySlug[ 'data-retrieval' ].slug ).toBe(
|
|
472
|
-
'data-retrieval'
|
|
473
|
-
);
|
|
474
|
-
expect( state.categoriesBySlug[ 'data-retrieval' ].label ).toBe(
|
|
475
|
-
'Data Retrieval'
|
|
476
|
-
);
|
|
477
|
-
} );
|
|
478
|
-
|
|
479
|
-
it( 'should filter out _embedded from server responses', () => {
|
|
480
|
-
const categories = [
|
|
481
|
-
{
|
|
482
|
-
slug: 'data-retrieval',
|
|
483
|
-
label: 'Data Retrieval',
|
|
484
|
-
description: 'Test category with embedded',
|
|
485
|
-
_embedded: {
|
|
486
|
-
author: { id: 1, name: 'Admin' },
|
|
487
|
-
},
|
|
488
|
-
},
|
|
489
|
-
];
|
|
490
|
-
|
|
491
|
-
const action = {
|
|
492
|
-
type: RECEIVE_CATEGORIES,
|
|
493
|
-
categories,
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
const state = reducer(
|
|
497
|
-
{ categoriesBySlug: defaultState, abilitiesByName: {} },
|
|
498
|
-
action
|
|
499
|
-
);
|
|
500
|
-
|
|
501
|
-
expect(
|
|
502
|
-
state.categoriesBySlug[ 'data-retrieval' ]
|
|
503
|
-
).not.toHaveProperty( '_embedded' );
|
|
504
|
-
} );
|
|
505
|
-
|
|
506
|
-
it( 'should preserve all valid category properties', () => {
|
|
507
|
-
const categories = [
|
|
508
|
-
{
|
|
509
|
-
slug: 'data-retrieval',
|
|
510
|
-
label: 'Data Retrieval',
|
|
511
|
-
description: 'Full test category.',
|
|
512
|
-
meta: {
|
|
513
|
-
priority: 'high',
|
|
514
|
-
color: 'blue',
|
|
515
|
-
},
|
|
516
|
-
// Extra properties that should be filtered out
|
|
517
|
-
_links: { self: { href: '/test' } },
|
|
518
|
-
_embedded: { test: 'value' },
|
|
519
|
-
extra_field: 'should be removed',
|
|
520
|
-
},
|
|
521
|
-
];
|
|
522
|
-
|
|
523
|
-
const action = {
|
|
524
|
-
type: RECEIVE_CATEGORIES,
|
|
525
|
-
categories,
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
const state = reducer(
|
|
529
|
-
{ categoriesBySlug: defaultState, abilitiesByName: {} },
|
|
530
|
-
action
|
|
531
|
-
);
|
|
532
|
-
const category = state.categoriesBySlug[ 'data-retrieval' ];
|
|
533
|
-
|
|
534
|
-
// Should have valid properties
|
|
535
|
-
expect( category.slug ).toBe( 'data-retrieval' );
|
|
536
|
-
expect( category.label ).toBe( 'Data Retrieval' );
|
|
537
|
-
expect( category.description ).toBe( 'Full test category.' );
|
|
538
|
-
expect( category.meta ).toEqual( {
|
|
539
|
-
priority: 'high',
|
|
540
|
-
color: 'blue',
|
|
541
|
-
} );
|
|
542
|
-
|
|
543
|
-
// Should NOT have invalid properties
|
|
544
|
-
expect( category ).not.toHaveProperty( '_links' );
|
|
545
|
-
expect( category ).not.toHaveProperty( '_embedded' );
|
|
546
|
-
expect( category ).not.toHaveProperty( 'extra_field' );
|
|
547
|
-
} );
|
|
548
|
-
|
|
549
|
-
it( 'should overwrite existing categories', () => {
|
|
550
|
-
const initialState = {
|
|
551
|
-
'existing-category': {
|
|
552
|
-
slug: 'existing-category',
|
|
553
|
-
label: 'Existing Category',
|
|
554
|
-
description: 'Already in store',
|
|
555
|
-
},
|
|
556
|
-
};
|
|
557
|
-
|
|
558
|
-
const categories = [
|
|
559
|
-
{
|
|
560
|
-
slug: 'data-retrieval',
|
|
561
|
-
label: 'Data Retrieval',
|
|
562
|
-
description: 'New category',
|
|
563
|
-
},
|
|
564
|
-
];
|
|
565
|
-
|
|
566
|
-
const action = {
|
|
567
|
-
type: RECEIVE_CATEGORIES,
|
|
568
|
-
categories,
|
|
569
|
-
};
|
|
570
|
-
|
|
571
|
-
const state = reducer(
|
|
572
|
-
{ categoriesBySlug: initialState, abilitiesByName: {} },
|
|
573
|
-
action
|
|
574
|
-
);
|
|
575
|
-
|
|
576
|
-
// Should only have new categories, old ones are replaced
|
|
577
|
-
expect( state.categoriesBySlug ).not.toHaveProperty(
|
|
578
|
-
'existing-category'
|
|
579
|
-
);
|
|
580
|
-
expect( state.categoriesBySlug ).toHaveProperty(
|
|
581
|
-
'data-retrieval'
|
|
582
|
-
);
|
|
583
|
-
} );
|
|
584
|
-
} );
|
|
585
|
-
|
|
586
|
-
describe( 'Edge cases', () => {
|
|
587
|
-
it( 'should handle undefined categories in RECEIVE_CATEGORIES', () => {
|
|
588
|
-
const action = {
|
|
589
|
-
type: RECEIVE_CATEGORIES,
|
|
590
|
-
categories: undefined,
|
|
591
|
-
};
|
|
592
|
-
|
|
593
|
-
const state = reducer(
|
|
594
|
-
{ categoriesBySlug: defaultState, abilitiesByName: {} },
|
|
595
|
-
action
|
|
596
|
-
);
|
|
597
|
-
|
|
598
|
-
expect( state.categoriesBySlug ).toEqual( defaultState );
|
|
599
|
-
} );
|
|
600
|
-
|
|
601
|
-
it( 'should handle empty categories array', () => {
|
|
602
|
-
const action = {
|
|
603
|
-
type: RECEIVE_CATEGORIES,
|
|
604
|
-
categories: [],
|
|
605
|
-
};
|
|
606
|
-
|
|
607
|
-
const state = reducer(
|
|
608
|
-
{ categoriesBySlug: defaultState, abilitiesByName: {} },
|
|
609
|
-
action
|
|
610
|
-
);
|
|
611
|
-
|
|
612
|
-
expect( state.categoriesBySlug ).toEqual( defaultState );
|
|
613
|
-
} );
|
|
614
|
-
|
|
615
|
-
it( 'should handle undefined properties gracefully', () => {
|
|
616
|
-
const categories = [
|
|
617
|
-
{
|
|
618
|
-
slug: 'minimal',
|
|
619
|
-
label: 'Minimal',
|
|
620
|
-
description: 'Minimal category with undefined meta',
|
|
621
|
-
meta: undefined,
|
|
622
|
-
},
|
|
623
|
-
];
|
|
624
|
-
|
|
625
|
-
const action = {
|
|
626
|
-
type: RECEIVE_CATEGORIES,
|
|
627
|
-
categories,
|
|
628
|
-
};
|
|
629
|
-
|
|
630
|
-
const state = reducer(
|
|
631
|
-
{ categoriesBySlug: defaultState, abilitiesByName: {} },
|
|
632
|
-
action
|
|
633
|
-
);
|
|
634
|
-
const category = state.categoriesBySlug.minimal;
|
|
635
|
-
|
|
636
|
-
expect( category.slug ).toBe( 'minimal' );
|
|
637
|
-
expect( category.label ).toBe( 'Minimal' );
|
|
638
|
-
expect( category.description ).toBe(
|
|
639
|
-
'Minimal category with undefined meta'
|
|
640
|
-
);
|
|
641
|
-
// Undefined properties should not be present
|
|
642
|
-
expect( category ).not.toHaveProperty( 'meta' );
|
|
643
|
-
} );
|
|
644
|
-
} );
|
|
645
|
-
|
|
646
195
|
describe( 'REGISTER_ABILITY_CATEGORY', () => {
|
|
647
196
|
it( 'should add category to the state', () => {
|
|
648
197
|
const category = {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
getAbilityCategories,
|
|
12
12
|
getAbilityCategory,
|
|
13
13
|
} from '../selectors';
|
|
14
|
-
import type { AbilitiesState } from '
|
|
14
|
+
import type { AbilitiesState } from '../types';
|
|
15
15
|
|
|
16
16
|
describe( 'Store Selectors', () => {
|
|
17
17
|
describe( 'getAbilities', () => {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { Ability, AbilityCategory } from '../types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The state shape for the abilities store.
|
|
8
|
+
*/
|
|
9
|
+
export interface AbilitiesState {
|
|
10
|
+
/**
|
|
11
|
+
* Map of ability names to ability objects.
|
|
12
|
+
*/
|
|
13
|
+
abilitiesByName: Record< string, Ability >;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Map of category slugs to category objects.
|
|
17
|
+
*/
|
|
18
|
+
categoriesBySlug: Record< string, AbilityCategory >;
|
|
19
|
+
}
|