Skip to main content
Glama
test-saola-exact.cjs5.88 kB
#!/usr/bin/env node const { spawn } = require('child_process'); const readline = require('readline'); const path = require('path'); const TEST_CASE = { name: 'Saola March to July 2025', credentials: { username: 'david+saola@umbrellacost.com', password: process.env.SAOLA_PASSWORD }, requests: [ { id: 1, method: 'tools/call', params: { name: 'authenticate_user', arguments: { username: 'david+saola@umbrellacost.com', password: process.env.SAOLA_PASSWORD } } }, { id: 2, method: 'tools/call', params: { name: 'api___invoices_caui', arguments: { startDate: '2025-03-01', endDate: '2025-07-31', periodGranLevel: 'month', groupBy: 'none', costType: '["cost", "discount"]', isUnblended: 'true' } } } ], expected: { // Values from MANUAL_ANSWERS.txt - 4 decimal places monthlyTotals: { '2025-03': 104755.0743, '2025-04': 111340.4244, '2025-05': 149774.2380, '2025-06': 165666.5701, '2025-07': 183920.5781 }, accountId: '932213950603' } }; function sendRequest(proc, request) { const jsonRequest = JSON.stringify({ jsonrpc: '2.0', ...request }); proc.stdin.write(jsonRequest + '\n'); } function parseResponse(line) { try { if (line.trim().startsWith('{') && line.includes('jsonrpc')) { return JSON.parse(line); } } catch (e) {} return null; } async function runTest() { return new Promise((resolve) => { console.log('Testing: Saola Account (March-July 2025)'); const result = { passed: false, errors: [] }; const proc = spawn('node', [path.join(__dirname, '../dist/index.js')], { env: process.env }); const rl = readline.createInterface({ input: proc.stdout, crlfDelay: Infinity }); rl.on('line', (line) => { if (!result.passed && line.includes('"serverInfo"')) { sendRequest(proc, TEST_CASE.requests[0]); } const response = parseResponse(line); if (response && response.id) { if (response.id === 1) { if (response.result) { sendRequest(proc, TEST_CASE.requests[1]); } else if (response.error) { console.log(` ❌ Authentication failed: ${response.error.message}`); result.errors.push(`Authentication failed: ${response.error.message}`); proc.kill(); resolve(result); } } else if (response.id === 2) { if (response.result) { let data = null; if (response.result.content && response.result.content[0] && response.result.content[0].text) { const content = response.result.content[0].text; const jsonMatch = content.match(/```json\n([\s\S]*?)\n```/); if (jsonMatch) { data = JSON.parse(jsonMatch[1]); } } if (data && Array.isArray(data)) { let allPassed = true; const actualByMonth = {}; data.forEach(row => { actualByMonth[row.usage_date] = row.total_cost; }); for (const [month, expectedCost] of Object.entries(TEST_CASE.expected.monthlyTotals)) { const actualCost = actualByMonth[month]; // Round both to 4 decimal places for comparison const roundedActual = actualCost ? Math.round(actualCost * 10000) / 10000 : undefined; const roundedExpected = Math.round(expectedCost * 10000) / 10000; if (actualCost === undefined) { console.log(` ❌ ${month}: Missing data`); result.errors.push(`${month}: Missing data`); allPassed = false; } else if (roundedActual !== roundedExpected) { console.log(` ❌ ${month}: Expected ${expectedCost}, got ${actualCost}`); result.errors.push(`${month}: Mismatch`); allPassed = false; } else { console.log(` ✅ ${month}: ${roundedActual} (matches to 4 decimal places)`); } } if (data[0] && data[0].account_id !== TEST_CASE.expected.accountId) { console.log(` ❌ Account ID: Expected ${TEST_CASE.expected.accountId}, got ${data[0].account_id}`); result.errors.push('Wrong account ID'); allPassed = false; } else if (data[0]) { console.log(` ✅ Account ID: ${data[0].account_id}`); } result.passed = allPassed; } else { result.errors.push('No data in response'); } } else if (response.error) { result.errors.push(`API call failed: ${response.error.message}`); } proc.kill(); resolve(result); } } }); proc.stderr.on('data', () => {}); sendRequest(proc, { jsonrpc: '2.0', method: 'initialize', params: { protocolVersion: '1.0.0', capabilities: {}, clientInfo: { name: 'test-client', version: '1.0.0' } }, id: 0 }); setTimeout(() => { if (!result.passed && result.errors.length === 0) { result.errors.push('Test timeout'); proc.kill(); resolve(result); } }, 30000); }); } runTest().then((result) => { if (result.passed) { console.log('\n✅ Saola test PASSED - Exact match!'); process.exit(0); } else { console.log('\n❌ Saola test FAILED'); process.exit(1); } });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/daviddraiumbrella/invoice-monitoring'

If you have feedback or need assistance with the MCP directory API, please join our Discord server