UNPKG

n8n-bookstack-agent-tool

Version:

Comprehensive BookStack API integration tool for n8n AI Agent with MCP framework compatibility

210 lines • 10.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.N8nIntegrationTester = void 0; const index_js_1 = require("../index.js"); const mcp_commands_js_1 = require("../commands/mcp-commands.js"); const gui_config_js_1 = require("../auth/gui-config.js"); class N8nIntegrationTester { constructor() { this.config = { baseUrl: 'https://wiki.l7cloud.io', authType: 'bearer', token: 'EnRkbVwqzNSyLaVo7olU8Wx8umGznKuE', tokenSecret: 'TyaJ0JHAenwRIgScmsffrCeSIlon4fZ2', timeout: 30000, retryAttempts: 3, retryDelay: 1000 }; this.tool = new index_js_1.BookStackN8nTool(this.config); } async runN8nIntegrationTests() { console.log('\nšŸ”§ N8N INTEGRATION TESTS'); console.log('========================'); await this.testMCPCommandRegistration(); await this.testGuiConfiguration(); await this.testAgentCommandDiscovery(); await this.testExecCommandInterface(); await this.testPolicyDrivenUsage(); console.log('\nāœ… N8n integration tests completed'); } async testMCPCommandRegistration() { console.log('\nšŸ“‹ Testing MCP Command Registration...'); try { console.log(' Testing command registry initialization...'); mcp_commands_js_1.MCPCommandRegistry.initialize(); const commands = mcp_commands_js_1.MCPCommandRegistry.getCommands(); console.log(` āœ… Command registry: ${commands.length} commands registered`); let validCommands = 0; for (const command of commands) { const hasName = typeof command.name === 'string' && command.name.length > 0; const hasDescription = typeof command.description === 'string'; const hasInputSchema = command.inputSchema && typeof command.inputSchema === 'object'; if (hasName && hasDescription && hasInputSchema) { validCommands++; } } console.log(` āœ… Valid command structures: ${validCommands}/${commands.length} (${(validCommands / commands.length * 100).toFixed(1)}%)`); const bookCommands = commands.filter((cmd) => cmd.name.toLowerCase().includes('book')); const pageCommands = commands.filter((cmd) => cmd.name.toLowerCase().includes('page')); const chapterCommands = commands.filter((cmd) => cmd.name.toLowerCase().includes('chapter')); console.log(` āœ… Book commands: ${bookCommands.length}`); console.log(` āœ… Page commands: ${pageCommands.length}`); console.log(` āœ… Chapter commands: ${chapterCommands.length}`); } catch (error) { console.log(` āŒ MCP command registration failed: ${error.message}`); } } async testGuiConfiguration() { console.log('\nšŸ–„ļø Testing GUI Configuration...'); try { console.log(' Testing GUI config form generation...'); const configForm = gui_config_js_1.N8nConfigGenerator.generateBookStackConfig(); const hasFields = Array.isArray(configForm) && configForm.length > 0; console.log(` āœ… Config form fields: ${hasFields ? configForm.length : 0}`); if (hasFields) { const requiredFields = ['baseUrl', 'authType', 'token']; let foundFields = 0; for (const field of requiredFields) { const fieldExists = configForm.some((f) => f.name === field); if (fieldExists) { foundFields++; console.log(` āœ… ${field}: Present`); } else { console.log(` āŒ ${field}: Missing`); } } console.log(` šŸ“Š Required fields: ${foundFields}/${requiredFields.length} (${(foundFields / requiredFields.length * 100).toFixed(1)}%)`); } console.log(' Testing form validation...'); const configSchema = gui_config_js_1.N8nConfigGenerator.generateConfigSchema(); const hasValidSchema = configSchema && typeof configSchema === 'object'; console.log(` āœ… Config schema generation: ${hasValidSchema ? 'Passed' : 'Failed'}`); } catch (error) { console.log(` āŒ GUI configuration test failed: ${error.message}`); } } async testAgentCommandDiscovery() { console.log('\nšŸ” Testing Agent Command Discovery...'); try { console.log(' Testing command introspection...'); const availableCommands = this.tool.getAvailableCommands(); console.log(` āœ… Available commands: ${availableCommands.length}`); let commandsWithMetadata = 0; for (const command of availableCommands) { const hasDescription = command.description && command.description.length > 0; const hasParameters = command.parameters && typeof command.parameters === 'object'; if (hasDescription && hasParameters) { commandsWithMetadata++; } } console.log(` āœ… Commands with metadata: ${commandsWithMetadata}/${availableCommands.length} (${(commandsWithMetadata / availableCommands.length * 100).toFixed(1)}%)`); const resourceCategories = ['books', 'pages', 'chapters', 'shelves', 'users', 'roles', 'attachments', 'tags']; let categoriesFound = 0; for (const category of resourceCategories) { const categoryCommands = availableCommands.filter((cmd) => cmd.name.toLowerCase().includes(category.slice(0, -1)) // Remove 's' for singular ); if (categoryCommands.length > 0) { categoriesFound++; console.log(` āœ… ${category}: ${categoryCommands.length} commands`); } else { console.log(` āŒ ${category}: No commands found`); } } console.log(` šŸ“Š Resource categories: ${categoriesFound}/${resourceCategories.length} (${(categoriesFound / resourceCategories.length * 100).toFixed(1)}%)`); } catch (error) { console.log(` āŒ Agent command discovery failed: ${error.message}`); } } async testExecCommandInterface() { console.log('\n⚔ Testing execCommand Interface...'); try { console.log(' Testing execCommand with valid parameters...'); const result = await this.tool.execCommand('listBooks', { count: 1 }); const isValidResult = result && (typeof result === 'object' || Array.isArray(result)); console.log(` āœ… execCommand result: ${isValidResult ? 'Valid' : 'Invalid'}`); if (isValidResult) { console.log(` āœ… Result type: ${Array.isArray(result) ? 'Array' : 'Object'}`); if (Array.isArray(result)) { console.log(` āœ… Result length: ${result.length}`); } } } catch (error) { console.log(` āŒ execCommand test failed: ${error.message}`); } try { console.log(' Testing execCommand with invalid command...'); await this.tool.execCommand('invalidCommand', {}); console.log(` āš ļø Invalid command: No error thrown`); } catch (error) { console.log(` āœ… Invalid command handling: Properly rejected`); } try { console.log(' Testing execCommand with missing parameters...'); await this.tool.execCommand('createBook', {}); // Missing required 'name' parameter console.log(` āš ļø Missing parameters: No error thrown`); } catch (error) { console.log(` āœ… Missing parameters handling: Properly rejected`); } } async testPolicyDrivenUsage() { console.log('\nšŸ“œ Testing Policy-Driven Usage...'); try { console.log(' Testing command execution policies...'); const readOnlyCommands = ['listBooks', 'getBook', 'listPages', 'listChapters']; let readOnlySuccess = 0; for (const command of readOnlyCommands) { try { await this.tool.execCommand(command, command === 'getBook' ? { id: 4 } : {}); readOnlySuccess++; console.log(` āœ… ${command}: Allowed`); } catch (error) { console.log(` āŒ ${command}: Blocked - ${error.message}`); } } console.log(` šŸ“Š Read-only operations: ${readOnlySuccess}/${readOnlyCommands.length} (${(readOnlySuccess / readOnlyCommands.length * 100).toFixed(1)}%)`); console.log(' Testing write operation policies...'); const writeCommands = ['createBook', 'updateBook', 'deleteBook']; let writeAttempts = 0; let writeBlocked = 0; for (const command of writeCommands) { writeAttempts++; try { const params = command === 'createBook' ? { name: 'Test Policy Book' } : command === 'updateBook' ? { id: 999999, name: 'Updated' } : { id: 999999 }; await this.tool.execCommand(command, params); console.log(` āš ļø ${command}: Allowed (unexpected)`); } catch (error) { writeBlocked++; const errorMessage = error.message; if (errorMessage.includes('403') || errorMessage.includes('permission') || errorMessage.includes('not found')) { console.log(` āœ… ${command}: Properly restricted`); } else { console.log(` āŒ ${command}: Unexpected error - ${errorMessage}`); } } } console.log(` šŸ“Š Write operations: ${writeBlocked}/${writeAttempts} properly restricted (${(writeBlocked / writeAttempts * 100).toFixed(1)}%)`); } catch (error) { console.log(` āŒ Policy-driven usage test failed: ${error.message}`); } } } exports.N8nIntegrationTester = N8nIntegrationTester; if (require.main === module) { const tester = new N8nIntegrationTester(); tester.runN8nIntegrationTests().catch(console.error); } //# sourceMappingURL=n8n-integration-test.js.map