n8n-bookstack-agent-tool
Version:
Comprehensive BookStack API integration tool for n8n AI Agent with MCP framework compatibility
277 lines ⢠12.1 kB
JavaScript
;
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