Skip to main content
Glama
index.test.ts7.62 kB
/** * Role Tools Tests * * Tests for role MCP tools. * * @package WP_Navigator_MCP * @since 2.6.0 */ import { describe, it, expect, beforeAll, vi } from 'vitest'; import { toolRegistry, ToolCategory } from '../../tool-registry/index.js'; import { registerRoleTools } from './index.js'; import type { ToolExecutionContext } from '../../tool-registry/types.js'; // Register tools once before all tests beforeAll(() => { // Register fresh registerRoleTools(); }); // ============================================================================= // Mock Context // ============================================================================= const createMockContext = (wpRequestMock?: any): ToolExecutionContext => ({ wpRequest: wpRequestMock || vi.fn(), config: { baseUrl: 'https://test.local', restApi: 'https://test.local/wp-json', wpnavBase: 'https://test.local/wp-json/wpnav/v1', wpnavIntrospect: 'https://test.local/wp-json/wpnav/v1/introspect', toggles: { enableWrites: false, toolTimeoutMs: 60000, }, }, logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn(), }, clampText: (text: string) => text, }); // ============================================================================= // Tool Registration Tests // ============================================================================= describe('Role Tools Registration', () => { it('should register wpnav_list_roles tool', () => { const tool = toolRegistry.getTool('wpnav_list_roles'); expect(tool).toBeDefined(); expect(tool?.category).toBe(ToolCategory.ROLES); }); it('should register wpnav_load_role tool', () => { const tool = toolRegistry.getTool('wpnav_load_role'); expect(tool).toBeDefined(); expect(tool?.category).toBe(ToolCategory.ROLES); }); }); // ============================================================================= // wpnav_list_roles Tests // ============================================================================= describe('wpnav_list_roles', () => { it('should return list of bundled roles', async () => { const tool = toolRegistry.getTool('wpnav_list_roles'); expect(tool).toBeDefined(); const result = await tool!.handler({}, createMockContext()); expect(result.content).toHaveLength(1); expect(result.content[0].type).toBe('text'); const data = JSON.parse(result.content[0].text!); expect(data.total).toBeGreaterThanOrEqual(4); // 4 bundled roles expect(data.roles).toBeInstanceOf(Array); expect(data.sources).toHaveProperty('bundled'); expect(data.sources).toHaveProperty('global'); expect(data.sources).toHaveProperty('project'); // Check for bundled roles const slugs = data.roles.map((r: any) => r.slug); expect(slugs).toContain('content-editor'); expect(slugs).toContain('developer'); expect(slugs).toContain('seo-specialist'); expect(slugs).toContain('site-admin'); }); it('should include role metadata', async () => { const tool = toolRegistry.getTool('wpnav_list_roles'); const result = await tool!.handler({}, createMockContext()); const data = JSON.parse(result.content[0].text!); const developer = data.roles.find((r: any) => r.slug === 'developer'); expect(developer).toBeDefined(); expect(developer.source).toBe('bundled'); expect(developer.description).toBeTruthy(); expect(developer.focus_areas).toBeInstanceOf(Array); expect(developer.avoid).toBeInstanceOf(Array); }); it('should include tool counts', async () => { const tool = toolRegistry.getTool('wpnav_list_roles'); const result = await tool!.handler({}, createMockContext()); const data = JSON.parse(result.content[0].text!); // Content editor has allowed tools and denied tools const contentEditor = data.roles.find((r: any) => r.slug === 'content-editor'); expect(contentEditor).toBeDefined(); expect(contentEditor.tools_allowed_count).toBeGreaterThan(0); expect(contentEditor.tools_denied_count).toBeGreaterThan(0); }); it('should show source location for each role', async () => { const tool = toolRegistry.getTool('wpnav_list_roles'); const result = await tool!.handler({}, createMockContext()); const data = JSON.parse(result.content[0].text!); // All bundled roles should have source: 'bundled' const bundledRoles = data.roles.filter((r: any) => r.source === 'bundled'); expect(bundledRoles.length).toBeGreaterThanOrEqual(4); }); }); // ============================================================================= // wpnav_load_role Tests // ============================================================================= describe('wpnav_load_role', () => { it('should return full role content for valid slug', async () => { const tool = toolRegistry.getTool('wpnav_load_role'); expect(tool).toBeDefined(); const result = await tool!.handler({ slug: 'developer' }, createMockContext()); expect(result.isError).toBeFalsy(); expect(result.content).toHaveLength(1); const data = JSON.parse(result.content[0].text!); expect(data.slug).toBe('developer'); expect(data.name).toBe('developer'); expect(data.description).toBeTruthy(); expect(data.context).toBeTruthy(); expect(data.focus_areas).toBeInstanceOf(Array); expect(data.avoid).toBeInstanceOf(Array); expect(data.tools).toBeDefined(); expect(data.tools.allowed).toBeInstanceOf(Array); expect(data.tools.denied).toBeInstanceOf(Array); }); it('should return error for invalid slug', async () => { const tool = toolRegistry.getTool('wpnav_load_role'); const result = await tool!.handler({ slug: 'nonexistent-role' }, createMockContext()); expect(result.isError).toBe(true); const data = JSON.parse(result.content[0].text!); expect(data.error).toContain('Role not found'); expect(data.available).toBeInstanceOf(Array); expect(data.hint).toBeDefined(); }); it('should return error for missing slug parameter', async () => { const tool = toolRegistry.getTool('wpnav_load_role'); const result = await tool!.handler({}, createMockContext()); expect(result.isError).toBe(true); const data = JSON.parse(result.content[0].text!); expect(data.error).toContain('Missing required parameter'); }); it('should return content-editor role', async () => { const tool = toolRegistry.getTool('wpnav_load_role'); const result = await tool!.handler({ slug: 'content-editor' }, createMockContext()); expect(result.isError).toBeFalsy(); const data = JSON.parse(result.content[0].text!); expect(data.slug).toBe('content-editor'); expect(data.tools.allowed.length).toBeGreaterThan(0); expect(data.tools.denied.length).toBeGreaterThan(0); }); it('should return site-admin role with full access', async () => { const tool = toolRegistry.getTool('wpnav_load_role'); const result = await tool!.handler({ slug: 'site-admin' }, createMockContext()); expect(result.isError).toBeFalsy(); const data = JSON.parse(result.content[0].text!); expect(data.slug).toBe('site-admin'); // Site admin typically has no denied tools expect(data.tools.denied).toBeInstanceOf(Array); }); it('should include source and version fields', async () => { const tool = toolRegistry.getTool('wpnav_load_role'); const result = await tool!.handler({ slug: 'developer' }, createMockContext()); const data = JSON.parse(result.content[0].text!); expect(data.source).toBe('bundled'); expect(data.schema_version).toBeDefined(); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/littlebearapps/wp-navigator-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server