/** * Tools Structure Tests * Validates that all tools have correct structure without DB connection * @author Descomplicar® | @link descomplicar.pt | @copyright 2026 */ import { documentsTools } from '../documents'; import { collectionsTools } from '../collections'; import { usersTools } from '../users'; import { groupsTools } from '../groups'; import { commentsTools } from '../comments'; import { sharesTools } from '../shares'; import { revisionsTools } from '../revisions'; import { eventsTools } from '../events'; import { attachmentsTools } from '../attachments'; import { fileOperationsTools } from '../file-operations'; import { oauthTools } from '../oauth'; import { authTools } from '../auth'; import { starsTools } from '../stars'; import { pinsTools } from '../pins'; import { viewsTools } from '../views'; import { reactionsTools } from '../reactions'; import { apiKeysTools } from '../api-keys'; import { webhooksTools } from '../webhooks'; import { backlinksTools } from '../backlinks'; import { searchQueriesTools } from '../search-queries'; import { teamsTools } from '../teams'; import { integrationsTools } from '../integrations'; import { notificationsTools } from '../notifications'; import { subscriptionsTools } from '../subscriptions'; import { templatesTools } from '../templates'; import { importsTools } from '../imports-tools'; import { emojisTools } from '../emojis'; import { userPermissionsTools } from '../user-permissions'; import { bulkOperationsTools } from '../bulk-operations'; import { advancedSearchTools } from '../advanced-search'; import { analyticsTools } from '../analytics'; import { exportImportTools } from '../export-import'; import { deskSyncTools } from '../desk-sync'; import { BaseTool } from '../../types/tools'; // Helper to validate tool structure function validateTool(tool: BaseTool): void { // Name should be snake_case (tools use names like list_documents, not outline_list_documents) expect(tool.name).toMatch(/^[a-z][a-z0-9_]*$/); // Description should exist and be non-empty expect(tool.description).toBeDefined(); expect(tool.description.length).toBeGreaterThan(10); // Input schema should have correct structure expect(tool.inputSchema).toBeDefined(); expect(tool.inputSchema.type).toBe('object'); expect(tool.inputSchema.properties).toBeDefined(); expect(typeof tool.inputSchema.properties).toBe('object'); // Handler should be a function expect(typeof tool.handler).toBe('function'); } // Helper to validate required properties in schema function validateRequiredProps(tool: BaseTool): void { if (tool.inputSchema.required) { expect(Array.isArray(tool.inputSchema.required)).toBe(true); // All required fields should exist in properties for (const req of tool.inputSchema.required) { expect(tool.inputSchema.properties).toHaveProperty(req); } } } describe('Tools Structure Validation', () => { describe('Documents Tools', () => { it('should export correct number of tools', () => { expect(documentsTools.length).toBeGreaterThanOrEqual(15); }); it('should have valid structure for all tools', () => { for (const tool of documentsTools) { validateTool(tool); validateRequiredProps(tool); } }); it('should include core document operations', () => { const names = documentsTools.map(t => t.name); expect(names).toContain('list_documents'); expect(names).toContain('get_document'); expect(names).toContain('create_document'); expect(names).toContain('update_document'); expect(names).toContain('delete_document'); expect(names).toContain('search_documents'); }); }); describe('Collections Tools', () => { it('should export correct number of tools', () => { expect(collectionsTools.length).toBeGreaterThanOrEqual(10); }); it('should have valid structure for all tools', () => { for (const tool of collectionsTools) { validateTool(tool); validateRequiredProps(tool); } }); it('should include core collection operations', () => { const names = collectionsTools.map(t => t.name); expect(names).toContain('list_collections'); expect(names).toContain('get_collection'); expect(names).toContain('create_collection'); expect(names).toContain('update_collection'); expect(names).toContain('delete_collection'); }); }); describe('Users Tools', () => { it('should export correct number of tools', () => { expect(usersTools.length).toBeGreaterThanOrEqual(5); }); it('should have valid structure for all tools', () => { for (const tool of usersTools) { validateTool(tool); validateRequiredProps(tool); } }); it('should include core user operations', () => { const names = usersTools.map(t => t.name); expect(names).toContain('outline_list_users'); expect(names).toContain('outline_get_user'); }); }); describe('Groups Tools', () => { it('should export correct number of tools', () => { expect(groupsTools.length).toBeGreaterThanOrEqual(5); }); it('should have valid structure for all tools', () => { for (const tool of groupsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Comments Tools', () => { it('should export correct number of tools', () => { expect(commentsTools.length).toBeGreaterThanOrEqual(4); }); it('should have valid structure for all tools', () => { for (const tool of commentsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Shares Tools', () => { it('should export correct number of tools', () => { expect(sharesTools.length).toBeGreaterThanOrEqual(3); }); it('should have valid structure for all tools', () => { for (const tool of sharesTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Revisions Tools', () => { it('should export correct number of tools', () => { expect(revisionsTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of revisionsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Events Tools', () => { it('should export correct number of tools', () => { expect(eventsTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of eventsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Attachments Tools', () => { it('should export correct number of tools', () => { expect(attachmentsTools.length).toBeGreaterThanOrEqual(3); }); it('should have valid structure for all tools', () => { for (const tool of attachmentsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('File Operations Tools', () => { it('should export tools', () => { expect(fileOperationsTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of fileOperationsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('OAuth Tools', () => { it('should export correct number of tools', () => { expect(oauthTools.length).toBeGreaterThanOrEqual(4); }); it('should have valid structure for all tools', () => { for (const tool of oauthTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Auth Tools', () => { it('should export tools', () => { expect(authTools.length).toBeGreaterThanOrEqual(1); }); it('should have valid structure for all tools', () => { for (const tool of authTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Stars Tools', () => { it('should export correct number of tools', () => { expect(starsTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of starsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Pins Tools', () => { it('should export correct number of tools', () => { expect(pinsTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of pinsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Views Tools', () => { it('should export tools', () => { expect(viewsTools.length).toBeGreaterThanOrEqual(1); }); it('should have valid structure for all tools', () => { for (const tool of viewsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Reactions Tools', () => { it('should export correct number of tools', () => { expect(reactionsTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of reactionsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('API Keys Tools', () => { it('should export correct number of tools', () => { expect(apiKeysTools.length).toBeGreaterThanOrEqual(3); }); it('should have valid structure for all tools', () => { for (const tool of apiKeysTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Webhooks Tools', () => { it('should export correct number of tools', () => { expect(webhooksTools.length).toBeGreaterThanOrEqual(3); }); it('should have valid structure for all tools', () => { for (const tool of webhooksTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Backlinks Tools', () => { it('should export tools', () => { expect(backlinksTools.length).toBeGreaterThanOrEqual(1); }); it('should have valid structure for all tools', () => { for (const tool of backlinksTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Search Queries Tools', () => { it('should export tools', () => { expect(searchQueriesTools.length).toBeGreaterThanOrEqual(1); }); it('should have valid structure for all tools', () => { for (const tool of searchQueriesTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Teams Tools', () => { it('should export correct number of tools', () => { expect(teamsTools.length).toBeGreaterThanOrEqual(3); }); it('should have valid structure for all tools', () => { for (const tool of teamsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Integrations Tools', () => { it('should export correct number of tools', () => { expect(integrationsTools.length).toBeGreaterThanOrEqual(3); }); it('should have valid structure for all tools', () => { for (const tool of integrationsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Notifications Tools', () => { it('should export correct number of tools', () => { expect(notificationsTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of notificationsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Subscriptions Tools', () => { it('should export correct number of tools', () => { expect(subscriptionsTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of subscriptionsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Templates Tools', () => { it('should export correct number of tools', () => { expect(templatesTools.length).toBeGreaterThanOrEqual(3); }); it('should have valid structure for all tools', () => { for (const tool of templatesTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Imports Tools', () => { it('should export tools', () => { expect(importsTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of importsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Emojis Tools', () => { it('should export correct number of tools', () => { expect(emojisTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of emojisTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('User Permissions Tools', () => { it('should export correct number of tools', () => { expect(userPermissionsTools.length).toBeGreaterThanOrEqual(2); }); it('should have valid structure for all tools', () => { for (const tool of userPermissionsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Bulk Operations Tools', () => { it('should export correct number of tools', () => { expect(bulkOperationsTools.length).toBeGreaterThanOrEqual(4); }); it('should have valid structure for all tools', () => { for (const tool of bulkOperationsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Advanced Search Tools', () => { it('should export correct number of tools', () => { expect(advancedSearchTools.length).toBeGreaterThanOrEqual(3); }); it('should have valid structure for all tools', () => { for (const tool of advancedSearchTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Analytics Tools', () => { it('should export correct number of tools', () => { expect(analyticsTools.length).toBeGreaterThanOrEqual(3); }); it('should have valid structure for all tools', () => { for (const tool of analyticsTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Export/Import Tools', () => { it('should export tools', () => { expect(exportImportTools.length).toBeGreaterThanOrEqual(1); }); it('should have valid structure for all tools', () => { for (const tool of exportImportTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Desk Sync Tools', () => { it('should export tools', () => { expect(deskSyncTools.length).toBeGreaterThanOrEqual(1); }); it('should have valid structure for all tools', () => { for (const tool of deskSyncTools) { validateTool(tool); validateRequiredProps(tool); } }); }); describe('Total Tools Count', () => { it('should have at least 164 tools total', () => { const allTools = [ ...documentsTools, ...collectionsTools, ...usersTools, ...groupsTools, ...commentsTools, ...sharesTools, ...revisionsTools, ...eventsTools, ...attachmentsTools, ...fileOperationsTools, ...oauthTools, ...authTools, ...starsTools, ...pinsTools, ...viewsTools, ...reactionsTools, ...apiKeysTools, ...webhooksTools, ...backlinksTools, ...searchQueriesTools, ...teamsTools, ...integrationsTools, ...notificationsTools, ...subscriptionsTools, ...templatesTools, ...importsTools, ...emojisTools, ...userPermissionsTools, ...bulkOperationsTools, ...advancedSearchTools, ...analyticsTools, ...exportImportTools, ...deskSyncTools ]; expect(allTools.length).toBeGreaterThanOrEqual(164); }); it('should have unique tool names', () => { const allTools = [ ...documentsTools, ...collectionsTools, ...usersTools, ...groupsTools, ...commentsTools, ...sharesTools, ...revisionsTools, ...eventsTools, ...attachmentsTools, ...fileOperationsTools, ...oauthTools, ...authTools, ...starsTools, ...pinsTools, ...viewsTools, ...reactionsTools, ...apiKeysTools, ...webhooksTools, ...backlinksTools, ...searchQueriesTools, ...teamsTools, ...integrationsTools, ...notificationsTools, ...subscriptionsTools, ...templatesTools, ...importsTools, ...emojisTools, ...userPermissionsTools, ...bulkOperationsTools, ...advancedSearchTools, ...analyticsTools, ...exportImportTools, ...deskSyncTools ]; const names = allTools.map(t => t.name); const uniqueNames = [...new Set(names)]; expect(names.length).toBe(uniqueNames.length); }); }); });