UNPKG

n8n-bookstack-agent-tool

Version:

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

277 lines • 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CliToolTester = void 0; const child_process_1 = require("child_process"); class CliToolTester { constructor() { this.baseUrl = 'https://wiki.l7cloud.io'; this.token = 'EnRkbVwqzNSyLaVo7olU8Wx8umGznKuE'; this.tokenSecret = 'TyaJ0JHAenwRIgScmsffrCeSIlon4fZ2'; } async runCliToolTests() { console.log('\n🧰 CLI TOOL VALIDATION TESTS'); console.log('============================'); await this.testCliToolTest(); await this.testCliToolCommands(); await this.testCliToolExec(); await this.testTypicalScenarios(); console.log('\nāœ… CLI tool validation tests completed'); } async testCliToolTest() { console.log('\nšŸ” Testing `bookstack-tool test` command...'); try { const result = await this.runCliCommand('test', [ '--url', this.baseUrl, '--token', this.token, '--token-secret', this.tokenSecret ]); console.log(' Command output:'); console.log(` ${result.stdout.split('\n').join('\n ')}`); if (result.exitCode === 0) { console.log(' āœ… CLI test command: Successful'); const hasConnectionTest = result.stdout.includes('connection') || result.stdout.includes('API'); const hasAuthTest = result.stdout.includes('auth') || result.stdout.includes('token'); console.log(` āœ… Connection test: ${hasConnectionTest ? 'Present' : 'Missing'}`); console.log(` āœ… Authentication test: ${hasAuthTest ? 'Present' : 'Missing'}`); } else { console.log(` āŒ CLI test command failed with exit code: ${result.exitCode}`); if (result.stderr) { console.log(` Error: ${result.stderr}`); } } } catch (error) { console.log(` āŒ CLI test command error: ${error.message}`); } } async testCliToolCommands() { console.log('\nšŸ“‹ Testing `bookstack-tool commands` command...'); try { const result = await this.runCliCommand('commands', [ '--url', this.baseUrl, '--token', this.token, '--token-secret', this.tokenSecret ]); if (result.exitCode === 0) { console.log(' āœ… CLI commands listing: Successful'); const commandLines = result.stdout.split('\n').filter(line => line.trim().length > 0); console.log(` āœ… Total commands listed: ${commandLines.length}`); const categories = ['books', 'pages', 'chapters', 'shelves', 'users', 'roles', 'attachments', 'tags']; let categoriesFound = 0; for (const category of categories) { const categoryCommands = commandLines.filter(line => line.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(` šŸ“Š Command categories: ${categoriesFound}/${categories.length} (${(categoriesFound / categories.length * 100).toFixed(1)}%)`); const crudOperations = ['list', 'get', 'create', 'update', 'delete']; let crudFound = 0; for (const operation of crudOperations) { const operationCommands = commandLines.filter(line => line.toLowerCase().includes(operation)); if (operationCommands.length > 0) { crudFound++; console.log(` āœ… ${operation} operations: ${operationCommands.length} commands`); } } console.log(` šŸ“Š CRUD operations: ${crudFound}/${crudOperations.length} (${(crudFound / crudOperations.length * 100).toFixed(1)}%)`); } else { console.log(` āŒ CLI commands listing failed with exit code: ${result.exitCode}`); if (result.stderr) { console.log(` Error: ${result.stderr}`); } } } catch (error) { console.log(` āŒ CLI commands listing error: ${error.message}`); } } async testCliToolExec() { console.log('\n⚔ Testing `bookstack-tool exec` command...'); const execTests = [ { name: 'List Books', command: 'listBooks', args: ['--count', '3'], expectSuccess: true }, { name: 'Get Specific Book', command: 'getBook', args: ['--id', '4'], expectSuccess: true }, { name: 'List Pages', command: 'listPages', args: ['--count', '2'], expectSuccess: true }, { name: 'Invalid Command', command: 'invalidCommand', args: [], expectSuccess: false } ]; let successfulTests = 0; const totalTests = execTests.length; for (const test of execTests) { try { console.log(` Testing ${test.name}...`); const args = [ 'exec', test.command, '--url', this.baseUrl, '--token', this.token, '--token-secret', this.tokenSecret, ...test.args ]; const result = await this.runCliCommand('', args); if (test.expectSuccess) { if (result.exitCode === 0) { console.log(` āœ… ${test.name}: Success`); try { const jsonOutput = JSON.parse(result.stdout); console.log(` āœ… JSON output: Valid (${typeof jsonOutput})`); if (Array.isArray(jsonOutput)) { console.log(` āœ… Result type: Array with ${jsonOutput.length} items`); } else if (typeof jsonOutput === 'object') { console.log(` āœ… Result type: Object with ${Object.keys(jsonOutput).length} properties`); } } catch (parseError) { console.log(` āš ļø JSON parsing: Failed - ${result.stdout.substring(0, 100)}...`); } successfulTests++; } else { console.log(` āŒ ${test.name}: Failed with exit code ${result.exitCode}`); if (result.stderr) { console.log(` Error: ${result.stderr}`); } } } else { if (result.exitCode !== 0) { console.log(` āœ… ${test.name}: Properly rejected`); successfulTests++; } else { console.log(` āŒ ${test.name}: Should have failed but succeeded`); } } } catch (error) { console.log(` āŒ ${test.name}: Error - ${error.message}`); } } console.log(`\n šŸ“Š Exec tests: ${successfulTests}/${totalTests} (${(successfulTests / totalTests * 100).toFixed(1)}%)`); } async testTypicalScenarios() { console.log('\nšŸŽÆ Testing typical usage scenarios...'); const scenarios = [ { name: 'Documentation Discovery', description: 'List all books to discover available documentation', command: 'listBooks', args: [] }, { name: 'Content Retrieval', description: 'Get specific book content', command: 'getBook', args: ['--id', '4'] }, { name: 'Search Operations', description: 'List pages with filtering', command: 'listPages', args: ['--count', '5'] }, { name: 'User Management', description: 'List system users', command: 'listUsers', args: ['--count', '3'] } ]; let successfulScenarios = 0; const totalScenarios = scenarios.length; for (const scenario of scenarios) { try { console.log(` Testing ${scenario.name}...`); console.log(` Description: ${scenario.description}`); const args = [ 'exec', scenario.command, '--url', this.baseUrl, '--token', this.token, '--token-secret', this.tokenSecret, ...scenario.args ]; const result = await this.runCliCommand('', args); if (result.exitCode === 0) { console.log(` āœ… ${scenario.name}: Success`); const outputLength = result.stdout.length; const hasContent = outputLength > 50; console.log(` āœ… Output quality: ${hasContent ? 'Good' : 'Minimal'} (${outputLength} chars)`); successfulScenarios++; } else { console.log(` āŒ ${scenario.name}: Failed`); if (result.stderr) { console.log(` Error: ${result.stderr.substring(0, 200)}...`); } } } catch (error) { console.log(` āŒ ${scenario.name}: Error - ${error.message}`); } } console.log(`\n šŸ“Š Typical scenarios: ${successfulScenarios}/${totalScenarios} (${(successfulScenarios / totalScenarios * 100).toFixed(1)}%)`); } async runCliCommand(subcommand, args) { return new Promise((resolve, reject) => { const fullArgs = subcommand ? [subcommand, ...args] : args; const child = (0, child_process_1.spawn)('node', ['dist/cli/cli-tool.js', ...fullArgs], { cwd: '/home/ubuntu/bookstack-n8n-tool', stdio: ['pipe', 'pipe', 'pipe'] }); let stdout = ''; let stderr = ''; child.stdout.on('data', (data) => { stdout += data.toString(); }); child.stderr.on('data', (data) => { stderr += data.toString(); }); child.on('close', (code) => { resolve({ stdout: stdout.trim(), stderr: stderr.trim(), exitCode: code || 0 }); }); child.on('error', (error) => { reject(error); }); setTimeout(() => { child.kill(); reject(new Error('CLI command timeout')); }, 30000); }); } } exports.CliToolTester = CliToolTester; if (require.main === module) { const tester = new CliToolTester(); tester.runCliToolTests().catch(console.error); } //# sourceMappingURL=cli-tool-test.js.map