@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,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/store/tests/reducer.test.ts"],
4
- "sourcesContent": ["/**\n * Tests for store reducer.\n */\n\n/**\n * Internal dependencies\n */\nimport reducer from '../reducer';\nimport {\n\tRECEIVE_ABILITIES,\n\tREGISTER_ABILITY,\n\tUNREGISTER_ABILITY,\n\tRECEIVE_CATEGORIES,\n\tREGISTER_ABILITY_CATEGORY,\n\tUNREGISTER_ABILITY_CATEGORY,\n} from '../constants';\n\ndescribe( 'Store Reducer', () => {\n\tdescribe( 'abilitiesByName', () => {\n\t\tconst defaultState = {};\n\n\t\tdescribe( 'RECEIVE_ABILITIES', () => {\n\t\t\tit( 'should add abilities to the state', () => {\n\t\t\t\tconst abilities = [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'test/ability1',\n\t\t\t\t\t\tlabel: 'Test Ability 1',\n\t\t\t\t\t\tdescription: 'First test ability',\n\t\t\t\t\t\tinput_schema: { type: 'object' },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'test/ability2',\n\t\t\t\t\t\tlabel: 'Test Ability 2',\n\t\t\t\t\t\tdescription: 'Second test ability',\n\t\t\t\t\t\toutput_schema: { type: 'object' },\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_ABILITIES,\n\t\t\t\t\tabilities,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: defaultState },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.abilitiesByName ).toHaveProperty(\n\t\t\t\t\t'test/ability1'\n\t\t\t\t);\n\t\t\t\texpect( state.abilitiesByName ).toHaveProperty(\n\t\t\t\t\t'test/ability2'\n\t\t\t\t);\n\t\t\t\texpect( state.abilitiesByName[ 'test/ability1' ].label ).toBe(\n\t\t\t\t\t'Test Ability 1'\n\t\t\t\t);\n\t\t\t\texpect( state.abilitiesByName[ 'test/ability2' ].label ).toBe(\n\t\t\t\t\t'Test Ability 2'\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\tit( 'should filter out _links from server responses', () => {\n\t\t\t\tconst abilities = [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'test/ability',\n\t\t\t\t\t\tlabel: 'Test Ability',\n\t\t\t\t\t\tdescription: 'Test ability with links',\n\t\t\t\t\t\t_links: {\n\t\t\t\t\t\t\tself: {\n\t\t\t\t\t\t\t\thref: '/wp-abilities/v1/abilities/test/ability',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcollection: { href: '/wp-abilities/v1/abilities' },\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_ABILITIES,\n\t\t\t\t\tabilities,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: defaultState },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect(\n\t\t\t\t\tstate.abilitiesByName[ 'test/ability' ]\n\t\t\t\t).not.toHaveProperty( '_links' );\n\t\t\t\texpect( state.abilitiesByName[ 'test/ability' ].name ).toBe(\n\t\t\t\t\t'test/ability'\n\t\t\t\t);\n\t\t\t\texpect( state.abilitiesByName[ 'test/ability' ].label ).toBe(\n\t\t\t\t\t'Test Ability'\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\tit( 'should filter out _embedded from server responses', () => {\n\t\t\t\tconst abilities = [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'test/ability',\n\t\t\t\t\t\tlabel: 'Test Ability',\n\t\t\t\t\t\tdescription: 'Test ability with embedded',\n\t\t\t\t\t\t_embedded: {\n\t\t\t\t\t\t\tauthor: { id: 1, name: 'Admin' },\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_ABILITIES,\n\t\t\t\t\tabilities,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: defaultState },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect(\n\t\t\t\t\tstate.abilitiesByName[ 'test/ability' ]\n\t\t\t\t).not.toHaveProperty( '_embedded' );\n\t\t\t} );\n\n\t\t\tit( 'should preserve all valid ability properties', () => {\n\t\t\t\tconst abilities = [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'test/ability',\n\t\t\t\t\t\tlabel: 'Test Ability',\n\t\t\t\t\t\tdescription: 'Full test ability.',\n\t\t\t\t\t\tinput_schema: { type: 'object' },\n\t\t\t\t\t\toutput_schema: { type: 'object' },\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\tcategory: 'test',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcallback: () => Promise.resolve( {} ),\n\t\t\t\t\t\tpermissionCallback: () => true,\n\t\t\t\t\t\t// Extra properties that should be filtered out\n\t\t\t\t\t\t_links: { self: { href: '/test' } },\n\t\t\t\t\t\t_embedded: { test: 'value' },\n\t\t\t\t\t\textra_field: 'should be removed',\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_ABILITIES,\n\t\t\t\t\tabilities,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: defaultState },\n\t\t\t\t\taction\n\t\t\t\t);\n\t\t\t\tconst ability = state.abilitiesByName[ 'test/ability' ];\n\n\t\t\t\t// Should have valid properties\n\t\t\t\texpect( ability.name ).toBe( 'test/ability' );\n\t\t\t\texpect( ability.label ).toBe( 'Test Ability' );\n\t\t\t\texpect( ability.description ).toBe( 'Full test ability.' );\n\t\t\t\texpect( ability.input_schema ).toEqual( { type: 'object' } );\n\t\t\t\texpect( ability.output_schema ).toEqual( { type: 'object' } );\n\t\t\t\texpect( ability.meta ).toEqual( { category: 'test' } );\n\t\t\t\texpect( ability.callback ).toBeDefined();\n\t\t\t\texpect( ability.permissionCallback ).toBeDefined();\n\n\t\t\t\t// Should NOT have invalid properties\n\t\t\t\texpect( ability ).not.toHaveProperty( '_links' );\n\t\t\t\texpect( ability ).not.toHaveProperty( '_embedded' );\n\t\t\t\texpect( ability ).not.toHaveProperty( 'extra_field' );\n\t\t\t} );\n\t\t} );\n\n\t\tdescribe( 'REGISTER_ABILITY', () => {\n\t\t\tit( 'should add ability to the state', () => {\n\t\t\t\tconst ability = {\n\t\t\t\t\tname: 'test/ability',\n\t\t\t\t\tlabel: 'Test Ability',\n\t\t\t\t\tdescription: 'Test ability',\n\t\t\t\t\tcallback: () => Promise.resolve( {} ),\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: REGISTER_ABILITY,\n\t\t\t\t\tability,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: defaultState },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.abilitiesByName ).toHaveProperty(\n\t\t\t\t\t'test/ability'\n\t\t\t\t);\n\t\t\t\texpect( state.abilitiesByName[ 'test/ability' ].label ).toBe(\n\t\t\t\t\t'Test Ability'\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\tit( 'should filter out extra properties when registering', () => {\n\t\t\t\tconst ability = {\n\t\t\t\t\tname: 'test/ability',\n\t\t\t\t\tlabel: 'Test Ability',\n\t\t\t\t\tdescription: 'Test ability',\n\t\t\t\t\tcallback: () => Promise.resolve( {} ),\n\t\t\t\t\t// Extra properties that should be filtered out\n\t\t\t\t\t_links: { self: { href: '/test' } },\n\t\t\t\t\textra_field: 'should be removed',\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: REGISTER_ABILITY,\n\t\t\t\t\tability,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: defaultState },\n\t\t\t\t\taction\n\t\t\t\t);\n\t\t\t\tconst registeredAbility =\n\t\t\t\t\tstate.abilitiesByName[ 'test/ability' ];\n\n\t\t\t\t// Should have valid properties\n\t\t\t\texpect( registeredAbility.name ).toBe( 'test/ability' );\n\t\t\t\texpect( registeredAbility.label ).toBe( 'Test Ability' );\n\t\t\t\texpect( registeredAbility.description ).toBe( 'Test ability' );\n\t\t\t\texpect( registeredAbility.callback ).toBeDefined();\n\n\t\t\t\t// Should NOT have invalid properties\n\t\t\t\texpect( registeredAbility ).not.toHaveProperty( '_links' );\n\t\t\t\texpect( registeredAbility ).not.toHaveProperty( 'extra_field' );\n\t\t\t} );\n\n\t\t\tit( 'should replace existing ability', () => {\n\t\t\t\tconst initialState = {\n\t\t\t\t\t'test/ability': {\n\t\t\t\t\t\tname: 'test/ability',\n\t\t\t\t\t\tlabel: 'Old Label',\n\t\t\t\t\t\tdescription: 'Old description',\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst ability = {\n\t\t\t\t\tname: 'test/ability',\n\t\t\t\t\tlabel: 'New Label',\n\t\t\t\t\tdescription: 'New description',\n\t\t\t\t\tinput_schema: { type: 'string' },\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: REGISTER_ABILITY,\n\t\t\t\t\tability,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: initialState },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.abilitiesByName[ 'test/ability' ].label ).toBe(\n\t\t\t\t\t'New Label'\n\t\t\t\t);\n\t\t\t\texpect(\n\t\t\t\t\tstate.abilitiesByName[ 'test/ability' ].description\n\t\t\t\t).toBe( 'New description' );\n\t\t\t\texpect(\n\t\t\t\t\tstate.abilitiesByName[ 'test/ability' ].input_schema\n\t\t\t\t).toEqual( { type: 'string' } );\n\t\t\t} );\n\t\t} );\n\n\t\tdescribe( 'UNREGISTER_ABILITY', () => {\n\t\t\tit( 'should remove ability from the state', () => {\n\t\t\t\tconst initialState = {\n\t\t\t\t\t'test/ability1': {\n\t\t\t\t\t\tname: 'test/ability1',\n\t\t\t\t\t\tlabel: 'Test Ability 1',\n\t\t\t\t\t\tdescription: 'First test ability',\n\t\t\t\t\t},\n\t\t\t\t\t'test/ability2': {\n\t\t\t\t\t\tname: 'test/ability2',\n\t\t\t\t\t\tlabel: 'Test Ability 2',\n\t\t\t\t\t\tdescription: 'Second test ability',\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: UNREGISTER_ABILITY,\n\t\t\t\t\tname: 'test/ability1',\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: initialState },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.abilitiesByName ).not.toHaveProperty(\n\t\t\t\t\t'test/ability1'\n\t\t\t\t);\n\t\t\t\texpect( state.abilitiesByName ).toHaveProperty(\n\t\t\t\t\t'test/ability2'\n\t\t\t\t);\n\t\t\t} );\n\t\t} );\n\n\t\tdescribe( 'Edge cases', () => {\n\t\t\tit( 'should handle unregistering non-existent ability', () => {\n\t\t\t\tconst initialState = {\n\t\t\t\t\t'test/ability': {\n\t\t\t\t\t\tname: 'test/ability',\n\t\t\t\t\t\tlabel: 'Test Ability',\n\t\t\t\t\t\tdescription: 'Test ability',\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: UNREGISTER_ABILITY,\n\t\t\t\t\tname: 'test/non-existent',\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: initialState },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.abilitiesByName ).toEqual( initialState );\n\t\t\t} );\n\n\t\t\tit( 'should handle undefined abilities in RECEIVE_ABILITIES', () => {\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_ABILITIES,\n\t\t\t\t\tabilities: undefined,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: defaultState },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.abilitiesByName ).toEqual( defaultState );\n\t\t\t} );\n\n\t\t\tit( 'should handle undefined ability in REGISTER_ABILITY', () => {\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: REGISTER_ABILITY,\n\t\t\t\t\tability: undefined,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: defaultState },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.abilitiesByName ).toEqual( defaultState );\n\t\t\t} );\n\n\t\t\tit( 'should handle undefined properties gracefully', () => {\n\t\t\t\tconst abilities = [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'test/minimal',\n\t\t\t\t\t\tlabel: 'Minimal',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Minimal ability with undefined properties',\n\t\t\t\t\t\tinput_schema: undefined,\n\t\t\t\t\t\toutput_schema: undefined,\n\t\t\t\t\t\tmeta: undefined,\n\t\t\t\t\t\tcallback: undefined,\n\t\t\t\t\t\tpermissionCallback: undefined,\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_ABILITIES,\n\t\t\t\t\tabilities,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ abilitiesByName: defaultState },\n\t\t\t\t\taction\n\t\t\t\t);\n\t\t\t\tconst ability = state.abilitiesByName[ 'test/minimal' ];\n\n\t\t\t\texpect( ability.name ).toBe( 'test/minimal' );\n\t\t\t\texpect( ability.label ).toBe( 'Minimal' );\n\t\t\t\texpect( ability.description ).toBe(\n\t\t\t\t\t'Minimal ability with undefined properties'\n\t\t\t\t);\n\t\t\t\t// Undefined properties should not be present\n\t\t\t\texpect( ability ).not.toHaveProperty( 'input_schema' );\n\t\t\t\texpect( ability ).not.toHaveProperty( 'output_schema' );\n\t\t\t\texpect( ability ).not.toHaveProperty( 'meta' );\n\t\t\t\texpect( ability ).not.toHaveProperty( 'callback' );\n\t\t\t\texpect( ability ).not.toHaveProperty( 'permissionCallback' );\n\t\t\t} );\n\t\t} );\n\t} );\n\n\tdescribe( 'categoriesBySlug', () => {\n\t\tconst defaultState = {};\n\n\t\tdescribe( 'RECEIVE_CATEGORIES', () => {\n\t\t\tit( 'should add categories to the state', () => {\n\t\t\t\tconst categories = [\n\t\t\t\t\t{\n\t\t\t\t\t\tslug: 'data-retrieval',\n\t\t\t\t\t\tlabel: 'Data Retrieval',\n\t\t\t\t\t\tdescription: 'Abilities that retrieve data',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tslug: 'user-management',\n\t\t\t\t\t\tlabel: 'User Management',\n\t\t\t\t\t\tdescription: 'Abilities for managing users',\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_CATEGORIES,\n\t\t\t\t\tcategories,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.categoriesBySlug ).toHaveProperty(\n\t\t\t\t\t'data-retrieval'\n\t\t\t\t);\n\t\t\t\texpect( state.categoriesBySlug ).toHaveProperty(\n\t\t\t\t\t'user-management'\n\t\t\t\t);\n\t\t\t\texpect( state.categoriesBySlug[ 'data-retrieval' ].label ).toBe(\n\t\t\t\t\t'Data Retrieval'\n\t\t\t\t);\n\t\t\t\texpect(\n\t\t\t\t\tstate.categoriesBySlug[ 'user-management' ].label\n\t\t\t\t).toBe( 'User Management' );\n\t\t\t} );\n\n\t\t\tit( 'should filter out _links from server responses', () => {\n\t\t\t\tconst categories = [\n\t\t\t\t\t{\n\t\t\t\t\t\tslug: 'data-retrieval',\n\t\t\t\t\t\tlabel: 'Data Retrieval',\n\t\t\t\t\t\tdescription: 'Test category with links',\n\t\t\t\t\t\t_links: {\n\t\t\t\t\t\t\tself: {\n\t\t\t\t\t\t\t\thref: '/wp-abilities/v1/categories/data-retrieval',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcollection: {\n\t\t\t\t\t\t\t\thref: '/wp-abilities/v1/categories',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_CATEGORIES,\n\t\t\t\t\tcategories,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect(\n\t\t\t\t\tstate.categoriesBySlug[ 'data-retrieval' ]\n\t\t\t\t).not.toHaveProperty( '_links' );\n\t\t\t\texpect( state.categoriesBySlug[ 'data-retrieval' ].slug ).toBe(\n\t\t\t\t\t'data-retrieval'\n\t\t\t\t);\n\t\t\t\texpect( state.categoriesBySlug[ 'data-retrieval' ].label ).toBe(\n\t\t\t\t\t'Data Retrieval'\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\tit( 'should filter out _embedded from server responses', () => {\n\t\t\t\tconst categories = [\n\t\t\t\t\t{\n\t\t\t\t\t\tslug: 'data-retrieval',\n\t\t\t\t\t\tlabel: 'Data Retrieval',\n\t\t\t\t\t\tdescription: 'Test category with embedded',\n\t\t\t\t\t\t_embedded: {\n\t\t\t\t\t\t\tauthor: { id: 1, name: 'Admin' },\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_CATEGORIES,\n\t\t\t\t\tcategories,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect(\n\t\t\t\t\tstate.categoriesBySlug[ 'data-retrieval' ]\n\t\t\t\t).not.toHaveProperty( '_embedded' );\n\t\t\t} );\n\n\t\t\tit( 'should preserve all valid category properties', () => {\n\t\t\t\tconst categories = [\n\t\t\t\t\t{\n\t\t\t\t\t\tslug: 'data-retrieval',\n\t\t\t\t\t\tlabel: 'Data Retrieval',\n\t\t\t\t\t\tdescription: 'Full test category.',\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\tpriority: 'high',\n\t\t\t\t\t\t\tcolor: 'blue',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t// Extra properties that should be filtered out\n\t\t\t\t\t\t_links: { self: { href: '/test' } },\n\t\t\t\t\t\t_embedded: { test: 'value' },\n\t\t\t\t\t\textra_field: 'should be removed',\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_CATEGORIES,\n\t\t\t\t\tcategories,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\t\t\t\tconst category = state.categoriesBySlug[ 'data-retrieval' ];\n\n\t\t\t\t// Should have valid properties\n\t\t\t\texpect( category.slug ).toBe( 'data-retrieval' );\n\t\t\t\texpect( category.label ).toBe( 'Data Retrieval' );\n\t\t\t\texpect( category.description ).toBe( 'Full test category.' );\n\t\t\t\texpect( category.meta ).toEqual( {\n\t\t\t\t\tpriority: 'high',\n\t\t\t\t\tcolor: 'blue',\n\t\t\t\t} );\n\n\t\t\t\t// Should NOT have invalid properties\n\t\t\t\texpect( category ).not.toHaveProperty( '_links' );\n\t\t\t\texpect( category ).not.toHaveProperty( '_embedded' );\n\t\t\t\texpect( category ).not.toHaveProperty( 'extra_field' );\n\t\t\t} );\n\n\t\t\tit( 'should overwrite existing categories', () => {\n\t\t\t\tconst initialState = {\n\t\t\t\t\t'existing-category': {\n\t\t\t\t\t\tslug: 'existing-category',\n\t\t\t\t\t\tlabel: 'Existing Category',\n\t\t\t\t\t\tdescription: 'Already in store',\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst categories = [\n\t\t\t\t\t{\n\t\t\t\t\t\tslug: 'data-retrieval',\n\t\t\t\t\t\tlabel: 'Data Retrieval',\n\t\t\t\t\t\tdescription: 'New category',\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_CATEGORIES,\n\t\t\t\t\tcategories,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: initialState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\t// Should only have new categories, old ones are replaced\n\t\t\t\texpect( state.categoriesBySlug ).not.toHaveProperty(\n\t\t\t\t\t'existing-category'\n\t\t\t\t);\n\t\t\t\texpect( state.categoriesBySlug ).toHaveProperty(\n\t\t\t\t\t'data-retrieval'\n\t\t\t\t);\n\t\t\t} );\n\t\t} );\n\n\t\tdescribe( 'Edge cases', () => {\n\t\t\tit( 'should handle undefined categories in RECEIVE_CATEGORIES', () => {\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_CATEGORIES,\n\t\t\t\t\tcategories: undefined,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.categoriesBySlug ).toEqual( defaultState );\n\t\t\t} );\n\n\t\t\tit( 'should handle empty categories array', () => {\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_CATEGORIES,\n\t\t\t\t\tcategories: [],\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.categoriesBySlug ).toEqual( defaultState );\n\t\t\t} );\n\n\t\t\tit( 'should handle undefined properties gracefully', () => {\n\t\t\t\tconst categories = [\n\t\t\t\t\t{\n\t\t\t\t\t\tslug: 'minimal',\n\t\t\t\t\t\tlabel: 'Minimal',\n\t\t\t\t\t\tdescription: 'Minimal category with undefined meta',\n\t\t\t\t\t\tmeta: undefined,\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: RECEIVE_CATEGORIES,\n\t\t\t\t\tcategories,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\t\t\t\tconst category = state.categoriesBySlug.minimal;\n\n\t\t\t\texpect( category.slug ).toBe( 'minimal' );\n\t\t\t\texpect( category.label ).toBe( 'Minimal' );\n\t\t\t\texpect( category.description ).toBe(\n\t\t\t\t\t'Minimal category with undefined meta'\n\t\t\t\t);\n\t\t\t\t// Undefined properties should not be present\n\t\t\t\texpect( category ).not.toHaveProperty( 'meta' );\n\t\t\t} );\n\t\t} );\n\n\t\tdescribe( 'REGISTER_ABILITY_CATEGORY', () => {\n\t\t\tit( 'should add category to the state', () => {\n\t\t\t\tconst category = {\n\t\t\t\t\tslug: 'test-category',\n\t\t\t\t\tlabel: 'Test Category',\n\t\t\t\t\tdescription: 'A test category',\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: REGISTER_ABILITY_CATEGORY,\n\t\t\t\t\tcategory,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.categoriesBySlug ).toHaveProperty(\n\t\t\t\t\t'test-category'\n\t\t\t\t);\n\t\t\t\texpect( state.categoriesBySlug[ 'test-category' ].label ).toBe(\n\t\t\t\t\t'Test Category'\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\tit( 'should add category with meta to the state', () => {\n\t\t\t\tconst category = {\n\t\t\t\t\tslug: 'test-category',\n\t\t\t\t\tlabel: 'Test Category',\n\t\t\t\t\tdescription: 'A test category',\n\t\t\t\t\tmeta: { color: 'blue', priority: 'high' },\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: REGISTER_ABILITY_CATEGORY,\n\t\t\t\t\tcategory,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect(\n\t\t\t\t\tstate.categoriesBySlug[ 'test-category' ].meta\n\t\t\t\t).toEqual( { color: 'blue', priority: 'high' } );\n\t\t\t} );\n\n\t\t\tit( 'should filter out extra properties when registering', () => {\n\t\t\t\tconst category = {\n\t\t\t\t\tslug: 'test-category',\n\t\t\t\t\tlabel: 'Test Category',\n\t\t\t\t\tdescription: 'A test category',\n\t\t\t\t\t// Extra properties that should be filtered out\n\t\t\t\t\t_links: { self: { href: '/test' } },\n\t\t\t\t\t_embedded: { author: { id: 1 } },\n\t\t\t\t\textra_field: 'should be removed',\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: REGISTER_ABILITY_CATEGORY,\n\t\t\t\t\tcategory,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\t\t\t\tconst registeredCategory =\n\t\t\t\t\tstate.categoriesBySlug[ 'test-category' ];\n\n\t\t\t\t// Should have valid properties\n\t\t\t\texpect( registeredCategory.slug ).toBe( 'test-category' );\n\t\t\t\texpect( registeredCategory.label ).toBe( 'Test Category' );\n\t\t\t\texpect( registeredCategory.description ).toBe(\n\t\t\t\t\t'A test category'\n\t\t\t\t);\n\n\t\t\t\t// Should NOT have invalid properties\n\t\t\t\texpect( registeredCategory ).not.toHaveProperty( '_links' );\n\t\t\t\texpect( registeredCategory ).not.toHaveProperty( '_embedded' );\n\t\t\t\texpect( registeredCategory ).not.toHaveProperty(\n\t\t\t\t\t'extra_field'\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\tit( 'should replace existing category', () => {\n\t\t\t\tconst initialState = {\n\t\t\t\t\t'test-category': {\n\t\t\t\t\t\tslug: 'test-category',\n\t\t\t\t\t\tlabel: 'Old Label',\n\t\t\t\t\t\tdescription: 'Old description',\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst category = {\n\t\t\t\t\tslug: 'test-category',\n\t\t\t\t\tlabel: 'New Label',\n\t\t\t\t\tdescription: 'New description',\n\t\t\t\t\tmeta: { color: 'red' },\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: REGISTER_ABILITY_CATEGORY,\n\t\t\t\t\tcategory,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: initialState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.categoriesBySlug[ 'test-category' ].label ).toBe(\n\t\t\t\t\t'New Label'\n\t\t\t\t);\n\t\t\t\texpect(\n\t\t\t\t\tstate.categoriesBySlug[ 'test-category' ].description\n\t\t\t\t).toBe( 'New description' );\n\t\t\t\texpect(\n\t\t\t\t\tstate.categoriesBySlug[ 'test-category' ].meta\n\t\t\t\t).toEqual( { color: 'red' } );\n\t\t\t} );\n\n\t\t\tit( 'should handle undefined category', () => {\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: REGISTER_ABILITY_CATEGORY,\n\t\t\t\t\tcategory: undefined,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: defaultState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.categoriesBySlug ).toEqual( defaultState );\n\t\t\t} );\n\t\t} );\n\n\t\tdescribe( 'UNREGISTER_ABILITY_CATEGORY', () => {\n\t\t\tit( 'should remove category from the state', () => {\n\t\t\t\tconst initialState = {\n\t\t\t\t\tcategory1: {\n\t\t\t\t\t\tslug: 'category1',\n\t\t\t\t\t\tlabel: 'Category 1',\n\t\t\t\t\t\tdescription: 'First category',\n\t\t\t\t\t},\n\t\t\t\t\tcategory2: {\n\t\t\t\t\t\tslug: 'category2',\n\t\t\t\t\t\tlabel: 'Category 2',\n\t\t\t\t\t\tdescription: 'Second category',\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: UNREGISTER_ABILITY_CATEGORY,\n\t\t\t\t\tslug: 'category1',\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: initialState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.categoriesBySlug ).not.toHaveProperty(\n\t\t\t\t\t'category1'\n\t\t\t\t);\n\t\t\t\texpect( state.categoriesBySlug ).toHaveProperty( 'category2' );\n\t\t\t} );\n\n\t\t\tit( 'should handle unregistering non-existent category', () => {\n\t\t\t\tconst initialState = {\n\t\t\t\t\t'test-category': {\n\t\t\t\t\t\tslug: 'test-category',\n\t\t\t\t\t\tlabel: 'Test Category',\n\t\t\t\t\t\tdescription: 'A test category',\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: UNREGISTER_ABILITY_CATEGORY,\n\t\t\t\t\tslug: 'non-existent',\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: initialState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.categoriesBySlug ).toEqual( initialState );\n\t\t\t} );\n\n\t\t\tit( 'should handle undefined slug', () => {\n\t\t\t\tconst initialState = {\n\t\t\t\t\t'test-category': {\n\t\t\t\t\t\tslug: 'test-category',\n\t\t\t\t\t\tlabel: 'Test Category',\n\t\t\t\t\t\tdescription: 'A test category',\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst action = {\n\t\t\t\t\ttype: UNREGISTER_ABILITY_CATEGORY,\n\t\t\t\t\tslug: undefined,\n\t\t\t\t};\n\n\t\t\t\tconst state = reducer(\n\t\t\t\t\t{ categoriesBySlug: initialState, abilitiesByName: {} },\n\t\t\t\t\taction\n\t\t\t\t);\n\n\t\t\t\texpect( state.categoriesBySlug ).toEqual( initialState );\n\t\t\t} );\n\t\t} );\n\t} );\n} );\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,523 +0,0 @@
1
- // packages/abilities/src/store/tests/resolvers.test.ts
2
- import { store as coreStore } from "@wordpress/core-data";
3
- import {
4
- getAbilities,
5
- getAbility,
6
- getAbilityCategories,
7
- getAbilityCategory
8
- } from "../resolvers";
9
- import { receiveAbilities, receiveCategories } from "../actions";
10
- import { ENTITY_KIND, ENTITY_NAME, ENTITY_NAME_CATEGORIES } from "../constants";
11
- jest.mock("@wordpress/core-data", () => ({
12
- store: "core"
13
- }));
14
- describe("Store Resolvers", () => {
15
- let mockDispatch;
16
- let mockRegistry;
17
- let mockSelect;
18
- beforeEach(() => {
19
- mockDispatch = jest.fn();
20
- mockSelect = jest.fn();
21
- mockRegistry = {
22
- resolveSelect: jest.fn(),
23
- select: jest.fn()
24
- };
25
- });
26
- describe("getAbilities", () => {
27
- it("should fetch and dispatch abilities from the server", async () => {
28
- const mockAbilities = [
29
- {
30
- name: "test/ability1",
31
- label: "Test Ability 1",
32
- description: "First test ability",
33
- category: "test-category",
34
- input_schema: { type: "object" },
35
- output_schema: { type: "object" }
36
- }
37
- ];
38
- const mockResolveSelect = {
39
- getEntityRecords: jest.fn().mockResolvedValue(mockAbilities)
40
- };
41
- const mockSelectInstance = {
42
- getAbilities: jest.fn().mockReturnValue([])
43
- // Store is empty
44
- };
45
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
46
- const resolver = getAbilities();
47
- await resolver({
48
- dispatch: mockDispatch,
49
- registry: mockRegistry,
50
- select: mockSelectInstance
51
- });
52
- expect(mockRegistry.resolveSelect).toHaveBeenCalledWith(
53
- coreStore
54
- );
55
- expect(mockResolveSelect.getEntityRecords).toHaveBeenCalledWith(
56
- ENTITY_KIND,
57
- ENTITY_NAME,
58
- { per_page: -1 }
59
- );
60
- expect(mockDispatch).toHaveBeenCalledWith(
61
- receiveAbilities(mockAbilities)
62
- );
63
- });
64
- it("should not fetch if store already has abilities", async () => {
65
- const existingAbilities = [
66
- {
67
- name: "test/ability1",
68
- label: "Test Ability 1",
69
- description: "First test ability",
70
- category: "data-retrieval",
71
- input_schema: { type: "object" },
72
- output_schema: { type: "object" }
73
- }
74
- ];
75
- const mockResolveSelect = {
76
- getEntityRecords: jest.fn()
77
- };
78
- const mockSelectInstance = {
79
- getAbilities: jest.fn().mockReturnValue(existingAbilities)
80
- // Store has data
81
- };
82
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
83
- const resolver = getAbilities({ category: "data-retrieval" });
84
- await resolver({
85
- dispatch: mockDispatch,
86
- registry: mockRegistry,
87
- select: mockSelectInstance
88
- });
89
- expect(mockResolveSelect.getEntityRecords).not.toHaveBeenCalled();
90
- expect(mockDispatch).not.toHaveBeenCalled();
91
- });
92
- it("should handle empty abilities", async () => {
93
- const mockResolveSelect = {
94
- getEntityRecords: jest.fn().mockResolvedValue([])
95
- };
96
- const mockSelectInstance = {
97
- getAbilities: jest.fn().mockReturnValue([])
98
- // Store is empty
99
- };
100
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
101
- const resolver = getAbilities();
102
- await resolver({
103
- dispatch: mockDispatch,
104
- registry: mockRegistry,
105
- select: mockSelectInstance
106
- });
107
- expect(mockDispatch).toHaveBeenCalledWith(
108
- receiveAbilities([])
109
- );
110
- });
111
- it("should handle null response", async () => {
112
- const mockResolveSelect = {
113
- getEntityRecords: jest.fn().mockResolvedValue(null)
114
- };
115
- const mockSelectInstance = {
116
- getAbilities: jest.fn().mockReturnValue([])
117
- // Store is empty
118
- };
119
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
120
- const resolver = getAbilities();
121
- await resolver({
122
- dispatch: mockDispatch,
123
- registry: mockRegistry,
124
- select: mockSelectInstance
125
- });
126
- expect(mockDispatch).toHaveBeenCalledWith(
127
- receiveAbilities([])
128
- );
129
- });
130
- it("should fetch all abilities in a single request", async () => {
131
- const allAbilities = [
132
- {
133
- name: "test/ability1",
134
- label: "Test Ability 1",
135
- description: "First test ability",
136
- category: "test-category",
137
- input_schema: { type: "object" },
138
- output_schema: { type: "object" }
139
- },
140
- {
141
- name: "test/ability2",
142
- label: "Test Ability 2",
143
- description: "Second test ability",
144
- category: "test-category",
145
- input_schema: { type: "object" },
146
- output_schema: { type: "object" }
147
- },
148
- {
149
- name: "test/ability3",
150
- label: "Test Ability 3",
151
- description: "Third test ability",
152
- category: "test-category",
153
- input_schema: { type: "object" },
154
- output_schema: { type: "object" }
155
- }
156
- ];
157
- const mockResolveSelect = {
158
- getEntityRecords: jest.fn().mockResolvedValue(allAbilities)
159
- };
160
- const mockSelectInstance = {
161
- getAbilities: jest.fn().mockReturnValue([])
162
- // Store is empty
163
- };
164
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
165
- const resolver = getAbilities();
166
- await resolver({
167
- dispatch: mockDispatch,
168
- registry: mockRegistry,
169
- select: mockSelectInstance
170
- });
171
- expect(mockResolveSelect.getEntityRecords).toHaveBeenCalledTimes(
172
- 1
173
- );
174
- expect(
175
- mockResolveSelect.getEntityRecords
176
- ).toHaveBeenNthCalledWith(1, ENTITY_KIND, ENTITY_NAME, {
177
- per_page: -1
178
- });
179
- expect(mockDispatch).toHaveBeenCalledWith(
180
- receiveAbilities(allAbilities)
181
- );
182
- });
183
- });
184
- describe("getAbility", () => {
185
- it("should fetch and dispatch a specific ability", async () => {
186
- const mockAbility = {
187
- name: "test/ability",
188
- label: "Test Ability",
189
- description: "Test ability description",
190
- category: "test-category",
191
- input_schema: { type: "object" },
192
- output_schema: { type: "object" }
193
- };
194
- const mockResolveSelect = {
195
- getEntityRecord: jest.fn().mockResolvedValue(mockAbility)
196
- };
197
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
198
- mockSelect.getAbility = jest.fn().mockReturnValue(null);
199
- const resolver = getAbility("test/ability");
200
- await resolver({
201
- dispatch: mockDispatch,
202
- registry: mockRegistry,
203
- select: mockSelect
204
- });
205
- expect(mockSelect.getAbility).toHaveBeenCalledWith(
206
- "test/ability"
207
- );
208
- expect(mockRegistry.resolveSelect).toHaveBeenCalledWith(
209
- coreStore
210
- );
211
- expect(mockResolveSelect.getEntityRecord).toHaveBeenCalledWith(
212
- ENTITY_KIND,
213
- ENTITY_NAME,
214
- "test/ability"
215
- );
216
- expect(mockDispatch).toHaveBeenCalled();
217
- expect(typeof mockDispatch.mock.calls[0][0]).toBe(
218
- "function"
219
- );
220
- });
221
- it("should not fetch if ability already exists in store", async () => {
222
- const existingAbility = {
223
- name: "test/ability",
224
- label: "Test Ability",
225
- description: "Already in store",
226
- category: "test-category",
227
- input_schema: { type: "object" },
228
- output_schema: { type: "object" },
229
- callback: jest.fn()
230
- };
231
- mockSelect.getAbility = jest.fn().mockReturnValue(existingAbility);
232
- const resolver = getAbility("test/ability");
233
- await resolver({
234
- dispatch: mockDispatch,
235
- registry: mockRegistry,
236
- select: mockSelect
237
- });
238
- expect(mockSelect.getAbility).toHaveBeenCalledWith(
239
- "test/ability"
240
- );
241
- expect(mockRegistry.resolveSelect).not.toHaveBeenCalled();
242
- expect(mockDispatch).not.toHaveBeenCalled();
243
- });
244
- it("should handle non-existent abilities", async () => {
245
- const mockResolveSelect = {
246
- getEntityRecord: jest.fn().mockResolvedValue(null)
247
- };
248
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
249
- mockSelect.getAbility = jest.fn().mockReturnValue(null);
250
- const resolver = getAbility("non-existent");
251
- await resolver({
252
- dispatch: mockDispatch,
253
- registry: mockRegistry,
254
- select: mockSelect
255
- });
256
- expect(mockResolveSelect.getEntityRecord).toHaveBeenCalledWith(
257
- ENTITY_KIND,
258
- ENTITY_NAME,
259
- "non-existent"
260
- );
261
- expect(mockDispatch).not.toHaveBeenCalled();
262
- });
263
- it("should handle valid namespaced ability names", async () => {
264
- const mockAbility = {
265
- name: "my-plugin/feature-action",
266
- label: "Namespaced Action",
267
- description: "Namespaced ability",
268
- category: "test-category",
269
- input_schema: { type: "object" },
270
- output_schema: { type: "object" }
271
- };
272
- const mockResolveSelect = {
273
- getEntityRecord: jest.fn().mockResolvedValue(mockAbility)
274
- };
275
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
276
- mockSelect.getAbility = jest.fn().mockReturnValue(null);
277
- const resolver = getAbility("my-plugin/feature-action");
278
- await resolver({
279
- dispatch: mockDispatch,
280
- registry: mockRegistry,
281
- select: mockSelect
282
- });
283
- expect(mockResolveSelect.getEntityRecord).toHaveBeenCalledWith(
284
- ENTITY_KIND,
285
- ENTITY_NAME,
286
- "my-plugin/feature-action"
287
- );
288
- expect(mockDispatch).toHaveBeenCalled();
289
- expect(typeof mockDispatch.mock.calls[0][0]).toBe(
290
- "function"
291
- );
292
- });
293
- });
294
- describe("getAbilityCategories", () => {
295
- it("should fetch and dispatch categories from the server", async () => {
296
- const mockCategories = [
297
- {
298
- slug: "data-retrieval",
299
- label: "Data Retrieval",
300
- description: "Abilities that retrieve data"
301
- },
302
- {
303
- slug: "user-management",
304
- label: "User Management",
305
- description: "Abilities for managing users"
306
- }
307
- ];
308
- const mockResolveSelect = {
309
- getEntityRecords: jest.fn().mockResolvedValue(mockCategories)
310
- };
311
- const mockSelectInstance = {
312
- getAbilityCategories: jest.fn().mockReturnValue([])
313
- };
314
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
315
- const resolver = getAbilityCategories();
316
- await resolver({
317
- dispatch: mockDispatch,
318
- registry: mockRegistry,
319
- select: mockSelectInstance
320
- });
321
- expect(mockRegistry.resolveSelect).toHaveBeenCalledWith(
322
- coreStore
323
- );
324
- expect(mockResolveSelect.getEntityRecords).toHaveBeenCalledWith(
325
- ENTITY_KIND,
326
- ENTITY_NAME_CATEGORIES,
327
- { per_page: -1 }
328
- );
329
- expect(mockDispatch).toHaveBeenCalledWith(
330
- receiveCategories(mockCategories)
331
- );
332
- });
333
- it("should not fetch if store already has categories", async () => {
334
- const existingCategories = [
335
- {
336
- slug: "data-retrieval",
337
- label: "Data Retrieval",
338
- description: "Abilities that retrieve data"
339
- }
340
- ];
341
- const mockResolveSelect = {
342
- getEntityRecords: jest.fn()
343
- };
344
- const mockSelectInstance = {
345
- getAbilityCategories: jest.fn().mockReturnValue(existingCategories)
346
- };
347
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
348
- const resolver = getAbilityCategories();
349
- await resolver({
350
- dispatch: mockDispatch,
351
- registry: mockRegistry,
352
- select: mockSelectInstance
353
- });
354
- expect(mockResolveSelect.getEntityRecords).not.toHaveBeenCalled();
355
- expect(mockDispatch).not.toHaveBeenCalled();
356
- });
357
- it("should fetch from server even when only client-registered categories exist", async () => {
358
- const clientOnlyCategories = [
359
- {
360
- slug: "client-category",
361
- label: "Client Category",
362
- description: "A category registered on the client",
363
- meta: {
364
- _clientRegistered: true
365
- }
366
- }
367
- ];
368
- const serverCategories = [
369
- {
370
- slug: "data-retrieval",
371
- label: "Data Retrieval",
372
- description: "Server category"
373
- },
374
- {
375
- slug: "user-management",
376
- label: "User Management",
377
- description: "Another server category"
378
- }
379
- ];
380
- const mockResolveSelect = {
381
- getEntityRecords: jest.fn().mockResolvedValue(serverCategories)
382
- };
383
- const mockSelectInstance = {
384
- getAbilityCategories: jest.fn().mockReturnValue(clientOnlyCategories)
385
- };
386
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
387
- const resolver = getAbilityCategories();
388
- await resolver({
389
- dispatch: mockDispatch,
390
- registry: mockRegistry,
391
- select: mockSelectInstance
392
- });
393
- expect(mockRegistry.resolveSelect).toHaveBeenCalledWith(
394
- coreStore
395
- );
396
- expect(mockResolveSelect.getEntityRecords).toHaveBeenCalledWith(
397
- ENTITY_KIND,
398
- ENTITY_NAME_CATEGORIES,
399
- { per_page: -1 }
400
- );
401
- expect(mockDispatch).toHaveBeenCalledWith(
402
- receiveCategories(serverCategories)
403
- );
404
- });
405
- it("should handle null response", async () => {
406
- const mockResolveSelect = {
407
- getEntityRecords: jest.fn().mockResolvedValue(null)
408
- };
409
- const mockSelectInstance = {
410
- getAbilityCategories: jest.fn().mockReturnValue([])
411
- };
412
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
413
- const resolver = getAbilityCategories();
414
- await resolver({
415
- dispatch: mockDispatch,
416
- registry: mockRegistry,
417
- select: mockSelectInstance
418
- });
419
- expect(mockDispatch).toHaveBeenCalledWith(
420
- receiveCategories([])
421
- );
422
- });
423
- });
424
- describe("getAbilityCategory", () => {
425
- it("should fetch and dispatch a specific category", async () => {
426
- const mockCategory = {
427
- slug: "data-retrieval",
428
- label: "Data Retrieval",
429
- description: "Abilities that retrieve data"
430
- };
431
- const mockResolveSelect = {
432
- getEntityRecord: jest.fn().mockResolvedValue(mockCategory)
433
- };
434
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
435
- mockSelect.getAbilityCategory = jest.fn().mockReturnValue(null);
436
- const resolver = getAbilityCategory("data-retrieval");
437
- await resolver({
438
- dispatch: mockDispatch,
439
- registry: mockRegistry,
440
- select: mockSelect
441
- });
442
- expect(mockSelect.getAbilityCategory).toHaveBeenCalledWith(
443
- "data-retrieval"
444
- );
445
- expect(mockRegistry.resolveSelect).toHaveBeenCalledWith(
446
- coreStore
447
- );
448
- expect(mockResolveSelect.getEntityRecord).toHaveBeenCalledWith(
449
- ENTITY_KIND,
450
- ENTITY_NAME_CATEGORIES,
451
- "data-retrieval"
452
- );
453
- expect(mockDispatch).toHaveBeenCalled();
454
- expect(typeof mockDispatch.mock.calls[0][0]).toBe(
455
- "function"
456
- );
457
- });
458
- it("should not fetch if category already exists in store", async () => {
459
- const existingCategory = {
460
- slug: "data-retrieval",
461
- label: "Data Retrieval",
462
- description: "Already in store"
463
- };
464
- mockSelect.getAbilityCategory = jest.fn().mockReturnValue(existingCategory);
465
- const resolver = getAbilityCategory("data-retrieval");
466
- await resolver({
467
- dispatch: mockDispatch,
468
- registry: mockRegistry,
469
- select: mockSelect
470
- });
471
- expect(mockSelect.getAbilityCategory).toHaveBeenCalledWith(
472
- "data-retrieval"
473
- );
474
- expect(mockRegistry.resolveSelect).not.toHaveBeenCalled();
475
- expect(mockDispatch).not.toHaveBeenCalled();
476
- });
477
- it("should handle non-existent categories", async () => {
478
- const mockResolveSelect = {
479
- getEntityRecord: jest.fn().mockResolvedValue(null)
480
- };
481
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
482
- mockSelect.getAbilityCategory = jest.fn().mockReturnValue(null);
483
- const resolver = getAbilityCategory("non-existent");
484
- await resolver({
485
- dispatch: mockDispatch,
486
- registry: mockRegistry,
487
- select: mockSelect
488
- });
489
- expect(mockResolveSelect.getEntityRecord).toHaveBeenCalledWith(
490
- ENTITY_KIND,
491
- ENTITY_NAME_CATEGORIES,
492
- "non-existent"
493
- );
494
- expect(mockDispatch).not.toHaveBeenCalled();
495
- });
496
- it("should handle categories with meta", async () => {
497
- const mockCategory = {
498
- slug: "user-management",
499
- label: "User Management",
500
- description: "Abilities for managing users",
501
- meta: {
502
- priority: "high"
503
- }
504
- };
505
- const mockResolveSelect = {
506
- getEntityRecord: jest.fn().mockResolvedValue(mockCategory)
507
- };
508
- mockRegistry.resolveSelect.mockReturnValue(mockResolveSelect);
509
- mockSelect.getAbilityCategory = jest.fn().mockReturnValue(null);
510
- const resolver = getAbilityCategory("user-management");
511
- await resolver({
512
- dispatch: mockDispatch,
513
- registry: mockRegistry,
514
- select: mockSelect
515
- });
516
- expect(mockDispatch).toHaveBeenCalled();
517
- expect(typeof mockDispatch.mock.calls[0][0]).toBe(
518
- "function"
519
- );
520
- });
521
- });
522
- });
523
- //# sourceMappingURL=resolvers.test.js.map