@wordpress/abilities 0.1.1-next.dc3f6d3c1.0 → 0.2.1-next.8b30e05b0.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.
@@ -1,726 +0,0 @@
1
- // packages/abilities/src/store/tests/reducer.test.ts
2
- import reducer from "../reducer";
3
- import {
4
- RECEIVE_ABILITIES,
5
- REGISTER_ABILITY,
6
- UNREGISTER_ABILITY,
7
- RECEIVE_CATEGORIES,
8
- REGISTER_ABILITY_CATEGORY,
9
- UNREGISTER_ABILITY_CATEGORY
10
- } from "../constants";
11
- describe("Store Reducer", () => {
12
- describe("abilitiesByName", () => {
13
- const defaultState = {};
14
- describe("RECEIVE_ABILITIES", () => {
15
- it("should add abilities to the state", () => {
16
- const abilities = [
17
- {
18
- name: "test/ability1",
19
- label: "Test Ability 1",
20
- description: "First test ability",
21
- input_schema: { type: "object" }
22
- },
23
- {
24
- name: "test/ability2",
25
- label: "Test Ability 2",
26
- description: "Second test ability",
27
- output_schema: { type: "object" }
28
- }
29
- ];
30
- const action = {
31
- type: RECEIVE_ABILITIES,
32
- abilities
33
- };
34
- const state = reducer(
35
- { abilitiesByName: defaultState },
36
- action
37
- );
38
- expect(state.abilitiesByName).toHaveProperty(
39
- "test/ability1"
40
- );
41
- expect(state.abilitiesByName).toHaveProperty(
42
- "test/ability2"
43
- );
44
- expect(state.abilitiesByName["test/ability1"].label).toBe(
45
- "Test Ability 1"
46
- );
47
- expect(state.abilitiesByName["test/ability2"].label).toBe(
48
- "Test Ability 2"
49
- );
50
- });
51
- it("should filter out _links from server responses", () => {
52
- const abilities = [
53
- {
54
- name: "test/ability",
55
- label: "Test Ability",
56
- description: "Test ability with links",
57
- _links: {
58
- self: {
59
- href: "/wp-abilities/v1/abilities/test/ability"
60
- },
61
- collection: { href: "/wp-abilities/v1/abilities" }
62
- }
63
- }
64
- ];
65
- const action = {
66
- type: RECEIVE_ABILITIES,
67
- abilities
68
- };
69
- const state = reducer(
70
- { abilitiesByName: defaultState },
71
- action
72
- );
73
- expect(
74
- state.abilitiesByName["test/ability"]
75
- ).not.toHaveProperty("_links");
76
- expect(state.abilitiesByName["test/ability"].name).toBe(
77
- "test/ability"
78
- );
79
- expect(state.abilitiesByName["test/ability"].label).toBe(
80
- "Test Ability"
81
- );
82
- });
83
- it("should filter out _embedded from server responses", () => {
84
- const abilities = [
85
- {
86
- name: "test/ability",
87
- label: "Test Ability",
88
- description: "Test ability with embedded",
89
- _embedded: {
90
- author: { id: 1, name: "Admin" }
91
- }
92
- }
93
- ];
94
- const action = {
95
- type: RECEIVE_ABILITIES,
96
- abilities
97
- };
98
- const state = reducer(
99
- { abilitiesByName: defaultState },
100
- action
101
- );
102
- expect(
103
- state.abilitiesByName["test/ability"]
104
- ).not.toHaveProperty("_embedded");
105
- });
106
- it("should preserve all valid ability properties", () => {
107
- const abilities = [
108
- {
109
- name: "test/ability",
110
- label: "Test Ability",
111
- description: "Full test ability.",
112
- input_schema: { type: "object" },
113
- output_schema: { type: "object" },
114
- meta: {
115
- category: "test"
116
- },
117
- callback: () => Promise.resolve({}),
118
- permissionCallback: () => true,
119
- // Extra properties that should be filtered out
120
- _links: { self: { href: "/test" } },
121
- _embedded: { test: "value" },
122
- extra_field: "should be removed"
123
- }
124
- ];
125
- const action = {
126
- type: RECEIVE_ABILITIES,
127
- abilities
128
- };
129
- const state = reducer(
130
- { abilitiesByName: defaultState },
131
- action
132
- );
133
- const ability = state.abilitiesByName["test/ability"];
134
- expect(ability.name).toBe("test/ability");
135
- expect(ability.label).toBe("Test Ability");
136
- expect(ability.description).toBe("Full test ability.");
137
- expect(ability.input_schema).toEqual({ type: "object" });
138
- expect(ability.output_schema).toEqual({ type: "object" });
139
- expect(ability.meta).toEqual({ category: "test" });
140
- expect(ability.callback).toBeDefined();
141
- expect(ability.permissionCallback).toBeDefined();
142
- expect(ability).not.toHaveProperty("_links");
143
- expect(ability).not.toHaveProperty("_embedded");
144
- expect(ability).not.toHaveProperty("extra_field");
145
- });
146
- });
147
- describe("REGISTER_ABILITY", () => {
148
- it("should add ability to the state", () => {
149
- const ability = {
150
- name: "test/ability",
151
- label: "Test Ability",
152
- description: "Test ability",
153
- callback: () => Promise.resolve({})
154
- };
155
- const action = {
156
- type: REGISTER_ABILITY,
157
- ability
158
- };
159
- const state = reducer(
160
- { abilitiesByName: defaultState },
161
- action
162
- );
163
- expect(state.abilitiesByName).toHaveProperty(
164
- "test/ability"
165
- );
166
- expect(state.abilitiesByName["test/ability"].label).toBe(
167
- "Test Ability"
168
- );
169
- });
170
- it("should filter out extra properties when registering", () => {
171
- const ability = {
172
- name: "test/ability",
173
- label: "Test Ability",
174
- description: "Test ability",
175
- callback: () => Promise.resolve({}),
176
- // Extra properties that should be filtered out
177
- _links: { self: { href: "/test" } },
178
- extra_field: "should be removed"
179
- };
180
- const action = {
181
- type: REGISTER_ABILITY,
182
- ability
183
- };
184
- const state = reducer(
185
- { abilitiesByName: defaultState },
186
- action
187
- );
188
- const registeredAbility = state.abilitiesByName["test/ability"];
189
- expect(registeredAbility.name).toBe("test/ability");
190
- expect(registeredAbility.label).toBe("Test Ability");
191
- expect(registeredAbility.description).toBe("Test ability");
192
- expect(registeredAbility.callback).toBeDefined();
193
- expect(registeredAbility).not.toHaveProperty("_links");
194
- expect(registeredAbility).not.toHaveProperty("extra_field");
195
- });
196
- it("should replace existing ability", () => {
197
- const initialState = {
198
- "test/ability": {
199
- name: "test/ability",
200
- label: "Old Label",
201
- description: "Old description"
202
- }
203
- };
204
- const ability = {
205
- name: "test/ability",
206
- label: "New Label",
207
- description: "New description",
208
- input_schema: { type: "string" }
209
- };
210
- const action = {
211
- type: REGISTER_ABILITY,
212
- ability
213
- };
214
- const state = reducer(
215
- { abilitiesByName: initialState },
216
- action
217
- );
218
- expect(state.abilitiesByName["test/ability"].label).toBe(
219
- "New Label"
220
- );
221
- expect(
222
- state.abilitiesByName["test/ability"].description
223
- ).toBe("New description");
224
- expect(
225
- state.abilitiesByName["test/ability"].input_schema
226
- ).toEqual({ type: "string" });
227
- });
228
- });
229
- describe("UNREGISTER_ABILITY", () => {
230
- it("should remove ability from the state", () => {
231
- const initialState = {
232
- "test/ability1": {
233
- name: "test/ability1",
234
- label: "Test Ability 1",
235
- description: "First test ability"
236
- },
237
- "test/ability2": {
238
- name: "test/ability2",
239
- label: "Test Ability 2",
240
- description: "Second test ability"
241
- }
242
- };
243
- const action = {
244
- type: UNREGISTER_ABILITY,
245
- name: "test/ability1"
246
- };
247
- const state = reducer(
248
- { abilitiesByName: initialState },
249
- action
250
- );
251
- expect(state.abilitiesByName).not.toHaveProperty(
252
- "test/ability1"
253
- );
254
- expect(state.abilitiesByName).toHaveProperty(
255
- "test/ability2"
256
- );
257
- });
258
- });
259
- describe("Edge cases", () => {
260
- it("should handle unregistering non-existent ability", () => {
261
- const initialState = {
262
- "test/ability": {
263
- name: "test/ability",
264
- label: "Test Ability",
265
- description: "Test ability"
266
- }
267
- };
268
- const action = {
269
- type: UNREGISTER_ABILITY,
270
- name: "test/non-existent"
271
- };
272
- const state = reducer(
273
- { abilitiesByName: initialState },
274
- action
275
- );
276
- expect(state.abilitiesByName).toEqual(initialState);
277
- });
278
- it("should handle undefined abilities in RECEIVE_ABILITIES", () => {
279
- const action = {
280
- type: RECEIVE_ABILITIES,
281
- abilities: void 0
282
- };
283
- const state = reducer(
284
- { abilitiesByName: defaultState },
285
- action
286
- );
287
- expect(state.abilitiesByName).toEqual(defaultState);
288
- });
289
- it("should handle undefined ability in REGISTER_ABILITY", () => {
290
- const action = {
291
- type: REGISTER_ABILITY,
292
- ability: void 0
293
- };
294
- const state = reducer(
295
- { abilitiesByName: defaultState },
296
- action
297
- );
298
- expect(state.abilitiesByName).toEqual(defaultState);
299
- });
300
- it("should handle undefined properties gracefully", () => {
301
- const abilities = [
302
- {
303
- name: "test/minimal",
304
- label: "Minimal",
305
- description: "Minimal ability with undefined properties",
306
- input_schema: void 0,
307
- output_schema: void 0,
308
- meta: void 0,
309
- callback: void 0,
310
- permissionCallback: void 0
311
- }
312
- ];
313
- const action = {
314
- type: RECEIVE_ABILITIES,
315
- abilities
316
- };
317
- const state = reducer(
318
- { abilitiesByName: defaultState },
319
- action
320
- );
321
- const ability = state.abilitiesByName["test/minimal"];
322
- expect(ability.name).toBe("test/minimal");
323
- expect(ability.label).toBe("Minimal");
324
- expect(ability.description).toBe(
325
- "Minimal ability with undefined properties"
326
- );
327
- expect(ability).not.toHaveProperty("input_schema");
328
- expect(ability).not.toHaveProperty("output_schema");
329
- expect(ability).not.toHaveProperty("meta");
330
- expect(ability).not.toHaveProperty("callback");
331
- expect(ability).not.toHaveProperty("permissionCallback");
332
- });
333
- });
334
- });
335
- describe("categoriesBySlug", () => {
336
- const defaultState = {};
337
- describe("RECEIVE_CATEGORIES", () => {
338
- it("should add categories to the state", () => {
339
- const categories = [
340
- {
341
- slug: "data-retrieval",
342
- label: "Data Retrieval",
343
- description: "Abilities that retrieve data"
344
- },
345
- {
346
- slug: "user-management",
347
- label: "User Management",
348
- description: "Abilities for managing users"
349
- }
350
- ];
351
- const action = {
352
- type: RECEIVE_CATEGORIES,
353
- categories
354
- };
355
- const state = reducer(
356
- { categoriesBySlug: defaultState, abilitiesByName: {} },
357
- action
358
- );
359
- expect(state.categoriesBySlug).toHaveProperty(
360
- "data-retrieval"
361
- );
362
- expect(state.categoriesBySlug).toHaveProperty(
363
- "user-management"
364
- );
365
- expect(state.categoriesBySlug["data-retrieval"].label).toBe(
366
- "Data Retrieval"
367
- );
368
- expect(
369
- state.categoriesBySlug["user-management"].label
370
- ).toBe("User Management");
371
- });
372
- it("should filter out _links from server responses", () => {
373
- const categories = [
374
- {
375
- slug: "data-retrieval",
376
- label: "Data Retrieval",
377
- description: "Test category with links",
378
- _links: {
379
- self: {
380
- href: "/wp-abilities/v1/categories/data-retrieval"
381
- },
382
- collection: {
383
- href: "/wp-abilities/v1/categories"
384
- }
385
- }
386
- }
387
- ];
388
- const action = {
389
- type: RECEIVE_CATEGORIES,
390
- categories
391
- };
392
- const state = reducer(
393
- { categoriesBySlug: defaultState, abilitiesByName: {} },
394
- action
395
- );
396
- expect(
397
- state.categoriesBySlug["data-retrieval"]
398
- ).not.toHaveProperty("_links");
399
- expect(state.categoriesBySlug["data-retrieval"].slug).toBe(
400
- "data-retrieval"
401
- );
402
- expect(state.categoriesBySlug["data-retrieval"].label).toBe(
403
- "Data Retrieval"
404
- );
405
- });
406
- it("should filter out _embedded from server responses", () => {
407
- const categories = [
408
- {
409
- slug: "data-retrieval",
410
- label: "Data Retrieval",
411
- description: "Test category with embedded",
412
- _embedded: {
413
- author: { id: 1, name: "Admin" }
414
- }
415
- }
416
- ];
417
- const action = {
418
- type: RECEIVE_CATEGORIES,
419
- categories
420
- };
421
- const state = reducer(
422
- { categoriesBySlug: defaultState, abilitiesByName: {} },
423
- action
424
- );
425
- expect(
426
- state.categoriesBySlug["data-retrieval"]
427
- ).not.toHaveProperty("_embedded");
428
- });
429
- it("should preserve all valid category properties", () => {
430
- const categories = [
431
- {
432
- slug: "data-retrieval",
433
- label: "Data Retrieval",
434
- description: "Full test category.",
435
- meta: {
436
- priority: "high",
437
- color: "blue"
438
- },
439
- // Extra properties that should be filtered out
440
- _links: { self: { href: "/test" } },
441
- _embedded: { test: "value" },
442
- extra_field: "should be removed"
443
- }
444
- ];
445
- const action = {
446
- type: RECEIVE_CATEGORIES,
447
- categories
448
- };
449
- const state = reducer(
450
- { categoriesBySlug: defaultState, abilitiesByName: {} },
451
- action
452
- );
453
- const category = state.categoriesBySlug["data-retrieval"];
454
- expect(category.slug).toBe("data-retrieval");
455
- expect(category.label).toBe("Data Retrieval");
456
- expect(category.description).toBe("Full test category.");
457
- expect(category.meta).toEqual({
458
- priority: "high",
459
- color: "blue"
460
- });
461
- expect(category).not.toHaveProperty("_links");
462
- expect(category).not.toHaveProperty("_embedded");
463
- expect(category).not.toHaveProperty("extra_field");
464
- });
465
- it("should overwrite existing categories", () => {
466
- const initialState = {
467
- "existing-category": {
468
- slug: "existing-category",
469
- label: "Existing Category",
470
- description: "Already in store"
471
- }
472
- };
473
- const categories = [
474
- {
475
- slug: "data-retrieval",
476
- label: "Data Retrieval",
477
- description: "New category"
478
- }
479
- ];
480
- const action = {
481
- type: RECEIVE_CATEGORIES,
482
- categories
483
- };
484
- const state = reducer(
485
- { categoriesBySlug: initialState, abilitiesByName: {} },
486
- action
487
- );
488
- expect(state.categoriesBySlug).not.toHaveProperty(
489
- "existing-category"
490
- );
491
- expect(state.categoriesBySlug).toHaveProperty(
492
- "data-retrieval"
493
- );
494
- });
495
- });
496
- describe("Edge cases", () => {
497
- it("should handle undefined categories in RECEIVE_CATEGORIES", () => {
498
- const action = {
499
- type: RECEIVE_CATEGORIES,
500
- categories: void 0
501
- };
502
- const state = reducer(
503
- { categoriesBySlug: defaultState, abilitiesByName: {} },
504
- action
505
- );
506
- expect(state.categoriesBySlug).toEqual(defaultState);
507
- });
508
- it("should handle empty categories array", () => {
509
- const action = {
510
- type: RECEIVE_CATEGORIES,
511
- categories: []
512
- };
513
- const state = reducer(
514
- { categoriesBySlug: defaultState, abilitiesByName: {} },
515
- action
516
- );
517
- expect(state.categoriesBySlug).toEqual(defaultState);
518
- });
519
- it("should handle undefined properties gracefully", () => {
520
- const categories = [
521
- {
522
- slug: "minimal",
523
- label: "Minimal",
524
- description: "Minimal category with undefined meta",
525
- meta: void 0
526
- }
527
- ];
528
- const action = {
529
- type: RECEIVE_CATEGORIES,
530
- categories
531
- };
532
- const state = reducer(
533
- { categoriesBySlug: defaultState, abilitiesByName: {} },
534
- action
535
- );
536
- const category = state.categoriesBySlug.minimal;
537
- expect(category.slug).toBe("minimal");
538
- expect(category.label).toBe("Minimal");
539
- expect(category.description).toBe(
540
- "Minimal category with undefined meta"
541
- );
542
- expect(category).not.toHaveProperty("meta");
543
- });
544
- });
545
- describe("REGISTER_ABILITY_CATEGORY", () => {
546
- it("should add category to the state", () => {
547
- const category = {
548
- slug: "test-category",
549
- label: "Test Category",
550
- description: "A test category"
551
- };
552
- const action = {
553
- type: REGISTER_ABILITY_CATEGORY,
554
- category
555
- };
556
- const state = reducer(
557
- { categoriesBySlug: defaultState, abilitiesByName: {} },
558
- action
559
- );
560
- expect(state.categoriesBySlug).toHaveProperty(
561
- "test-category"
562
- );
563
- expect(state.categoriesBySlug["test-category"].label).toBe(
564
- "Test Category"
565
- );
566
- });
567
- it("should add category with meta to the state", () => {
568
- const category = {
569
- slug: "test-category",
570
- label: "Test Category",
571
- description: "A test category",
572
- meta: { color: "blue", priority: "high" }
573
- };
574
- const action = {
575
- type: REGISTER_ABILITY_CATEGORY,
576
- category
577
- };
578
- const state = reducer(
579
- { categoriesBySlug: defaultState, abilitiesByName: {} },
580
- action
581
- );
582
- expect(
583
- state.categoriesBySlug["test-category"].meta
584
- ).toEqual({ color: "blue", priority: "high" });
585
- });
586
- it("should filter out extra properties when registering", () => {
587
- const category = {
588
- slug: "test-category",
589
- label: "Test Category",
590
- description: "A test category",
591
- // Extra properties that should be filtered out
592
- _links: { self: { href: "/test" } },
593
- _embedded: { author: { id: 1 } },
594
- extra_field: "should be removed"
595
- };
596
- const action = {
597
- type: REGISTER_ABILITY_CATEGORY,
598
- category
599
- };
600
- const state = reducer(
601
- { categoriesBySlug: defaultState, abilitiesByName: {} },
602
- action
603
- );
604
- const registeredCategory = state.categoriesBySlug["test-category"];
605
- expect(registeredCategory.slug).toBe("test-category");
606
- expect(registeredCategory.label).toBe("Test Category");
607
- expect(registeredCategory.description).toBe(
608
- "A test category"
609
- );
610
- expect(registeredCategory).not.toHaveProperty("_links");
611
- expect(registeredCategory).not.toHaveProperty("_embedded");
612
- expect(registeredCategory).not.toHaveProperty(
613
- "extra_field"
614
- );
615
- });
616
- it("should replace existing category", () => {
617
- const initialState = {
618
- "test-category": {
619
- slug: "test-category",
620
- label: "Old Label",
621
- description: "Old description"
622
- }
623
- };
624
- const category = {
625
- slug: "test-category",
626
- label: "New Label",
627
- description: "New description",
628
- meta: { color: "red" }
629
- };
630
- const action = {
631
- type: REGISTER_ABILITY_CATEGORY,
632
- category
633
- };
634
- const state = reducer(
635
- { categoriesBySlug: initialState, abilitiesByName: {} },
636
- action
637
- );
638
- expect(state.categoriesBySlug["test-category"].label).toBe(
639
- "New Label"
640
- );
641
- expect(
642
- state.categoriesBySlug["test-category"].description
643
- ).toBe("New description");
644
- expect(
645
- state.categoriesBySlug["test-category"].meta
646
- ).toEqual({ color: "red" });
647
- });
648
- it("should handle undefined category", () => {
649
- const action = {
650
- type: REGISTER_ABILITY_CATEGORY,
651
- category: void 0
652
- };
653
- const state = reducer(
654
- { categoriesBySlug: defaultState, abilitiesByName: {} },
655
- action
656
- );
657
- expect(state.categoriesBySlug).toEqual(defaultState);
658
- });
659
- });
660
- describe("UNREGISTER_ABILITY_CATEGORY", () => {
661
- it("should remove category from the state", () => {
662
- const initialState = {
663
- category1: {
664
- slug: "category1",
665
- label: "Category 1",
666
- description: "First category"
667
- },
668
- category2: {
669
- slug: "category2",
670
- label: "Category 2",
671
- description: "Second category"
672
- }
673
- };
674
- const action = {
675
- type: UNREGISTER_ABILITY_CATEGORY,
676
- slug: "category1"
677
- };
678
- const state = reducer(
679
- { categoriesBySlug: initialState, abilitiesByName: {} },
680
- action
681
- );
682
- expect(state.categoriesBySlug).not.toHaveProperty(
683
- "category1"
684
- );
685
- expect(state.categoriesBySlug).toHaveProperty("category2");
686
- });
687
- it("should handle unregistering non-existent category", () => {
688
- const initialState = {
689
- "test-category": {
690
- slug: "test-category",
691
- label: "Test Category",
692
- description: "A test category"
693
- }
694
- };
695
- const action = {
696
- type: UNREGISTER_ABILITY_CATEGORY,
697
- slug: "non-existent"
698
- };
699
- const state = reducer(
700
- { categoriesBySlug: initialState, abilitiesByName: {} },
701
- action
702
- );
703
- expect(state.categoriesBySlug).toEqual(initialState);
704
- });
705
- it("should handle undefined slug", () => {
706
- const initialState = {
707
- "test-category": {
708
- slug: "test-category",
709
- label: "Test Category",
710
- description: "A test category"
711
- }
712
- };
713
- const action = {
714
- type: UNREGISTER_ABILITY_CATEGORY,
715
- slug: void 0
716
- };
717
- const state = reducer(
718
- { categoriesBySlug: initialState, abilitiesByName: {} },
719
- action
720
- );
721
- expect(state.categoriesBySlug).toEqual(initialState);
722
- });
723
- });
724
- });
725
- });
726
- //# sourceMappingURL=reducer.test.js.map