const axios = require('axios');
const jwt = require('jsonwebtoken');
const SERVER_BASE = 'http://localhost:3000';
// Test credentials
const SAOLA_CREDS = { username: 'david+saola@umbrellacost.com', password: 'Dsamsung1!' };
const ALLCLOUD_CREDS = { username: 'david+allcloud@umbrellacost.com', password: 'B4*zcI7#F7poEC' };
const DEMO_CREDS = { username: 'demo@test.com', password: 'demo' };
class TestRunner {
constructor() {
this.testResults = [];
this.tokens = {};
}
log(test, status, message = '') {
const result = `${status === 'PASS' ? 'โ
' : status === 'FAIL' ? 'โ' : 'โ ๏ธ'} ${test}: ${message}`;
console.log(result);
this.testResults.push({ test, status, message });
}
async authenticate(account, creds) {
try {
const response = await axios.post(`${SERVER_BASE}/auth`, creds, {
headers: { 'Content-Type': 'application/json' }
});
if (response.data?.bearerToken) {
this.tokens[account] = response.data.bearerToken;
this.log(`Auth ${account}`, 'PASS', `Token received: ${response.data.bearerToken.substring(0, 20)}...`);
return true;
} else {
this.log(`Auth ${account}`, 'FAIL', 'No token in response');
return false;
}
} catch (error) {
this.log(`Auth ${account}`, 'FAIL', error.response?.data?.error || error.message);
return false;
}
}
async testMCPEndpoint(account, method, params = {}) {
try {
const token = this.tokens[account];
if (!token) {
this.log(`MCP ${account} ${method}`, 'FAIL', 'No token available');
return false;
}
const payload = {
jsonrpc: '2.0',
id: 1,
method,
params
};
const response = await axios.post(`${SERVER_BASE}/mcp`, payload, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
if (response.data?.result || response.data?.id === 1) {
this.log(`MCP ${account} ${method}`, 'PASS', JSON.stringify(response.data).substring(0, 100));
return response.data;
} else {
this.log(`MCP ${account} ${method}`, 'FAIL', 'Invalid response format');
return false;
}
} catch (error) {
this.log(`MCP ${account} ${method}`, 'FAIL', error.response?.data?.error || error.message);
return false;
}
}
async testTokenDecoding(account) {
try {
const token = this.tokens[account];
const decoded = jwt.decode(token);
if (decoded?.username && decoded?.exp) {
const expiryTime = new Date(decoded.exp * 1000);
this.log(`Token ${account}`, 'PASS', `User: ${decoded.username}, Expires: ${expiryTime.toLocaleString()}`);
return true;
} else {
this.log(`Token ${account}`, 'FAIL', 'Invalid token structure');
return false;
}
} catch (error) {
this.log(`Token ${account}`, 'FAIL', error.message);
return false;
}
}
async runAllTests() {
console.log('๐ Starting comprehensive MCP server tests...\n');
// Test 1: Authentication for all accounts
console.log('๐ Testing Authentication...');
const saolaAuth = await this.authenticate('SAOLA', SAOLA_CREDS);
const allcloudAuth = await this.authenticate('ALLCLOUD', ALLCLOUD_CREDS);
const demoAuth = await this.authenticate('DEMO', DEMO_CREDS);
// Test 2: Token structure validation
console.log('\n๐ Testing Token Structure...');
if (saolaAuth) await this.testTokenDecoding('SAOLA');
if (allcloudAuth) await this.testTokenDecoding('ALLCLOUD');
if (demoAuth) await this.testTokenDecoding('DEMO');
// Test 3: MCP Protocol - Initialize
console.log('\n๐ Testing MCP Initialize...');
const accounts = ['SAOLA', 'ALLCLOUD', 'DEMO'].filter(acc => this.tokens[acc]);
for (const account of accounts) {
await this.testMCPEndpoint(account, 'initialize', {
protocolVersion: '2024-11-05',
capabilities: { tools: {} },
clientInfo: { name: 'test-client', version: '1.0.0' }
});
}
// Test 4: MCP Protocol - Tools List
console.log('\n๐ Testing MCP Tools List...');
for (const account of accounts) {
await this.testMCPEndpoint(account, 'tools/list');
}
// Test 5: MCP Protocol - Tool Calls
console.log('\n๐ Testing MCP Tool Calls...');
for (const account of accounts) {
// Test get_accounts
await this.testMCPEndpoint(account, 'tools/call', {
name: 'get_accounts',
arguments: {}
});
// Test get_organizations (should work for authenticated accounts)
if (account !== 'DEMO') {
await this.testMCPEndpoint(account, 'tools/call', {
name: 'get_organizations',
arguments: {}
});
}
}
// Test 6: Multi-user isolation
console.log('\n๐ Testing Multi-user Isolation...');
if (this.tokens.SAOLA && this.tokens.ALLCLOUD) {
// Try using SAOLA token with ALLCLOUD data
try {
const response = await axios.post(`${SERVER_BASE}/mcp`, {
jsonrpc: '2.0',
id: 1,
method: 'tools/call',
params: { name: 'get_accounts', arguments: {} }
}, {
headers: {
'Authorization': `Bearer ${this.tokens.SAOLA}`,
'Content-Type': 'application/json'
}
});
this.log('Multi-user isolation', 'PASS', 'Each token maintains its own session');
} catch (error) {
this.log('Multi-user isolation', 'FAIL', 'Token isolation failed');
}
}
// Test 7: Invalid token handling
console.log('\n๐ Testing Security...');
try {
await axios.post(`${SERVER_BASE}/mcp`, {
jsonrpc: '2.0',
id: 1,
method: 'tools/list'
}, {
headers: {
'Authorization': 'Bearer invalid-token',
'Content-Type': 'application/json'
}
});
this.log('Security - Invalid token', 'FAIL', 'Server accepted invalid token');
} catch (error) {
if (error.response?.status === 401) {
this.log('Security - Invalid token', 'PASS', 'Server properly rejected invalid token');
} else {
this.log('Security - Invalid token', 'FAIL', 'Unexpected error response');
}
}
// Summary
console.log('\n๐ Test Summary:');
const passed = this.testResults.filter(r => r.status === 'PASS').length;
const failed = this.testResults.filter(r => r.status === 'FAIL').length;
const warnings = this.testResults.filter(r => r.status === 'WARN').length;
console.log(`โ
Passed: ${passed}`);
console.log(`โ Failed: ${failed}`);
console.log(`โ ๏ธ Warnings: ${warnings}`);
console.log(`๐ Success Rate: ${((passed / this.testResults.length) * 100).toFixed(1)}%`);
if (failed === 0) {
console.log('\n๐ ALL TESTS PASSED! Server is production-ready! ๐');
} else {
console.log('\nโ ๏ธ Some tests failed. Review the results above.');
}
return { passed, failed, warnings, total: this.testResults.length };
}
}
// Run tests
const runner = new TestRunner();
runner.runAllTests().catch(console.error);