Files
spore-ui/test/mock-test.js
2025-09-17 22:22:11 +02:00

286 lines
7.8 KiB
JavaScript

#!/usr/bin/env node
/**
* Mock Server Integration Test
*
* Tests the mock server functionality to ensure all endpoints work correctly
*/
const http = require('http');
const MOCK_SERVER_URL = 'http://localhost:3002';
const TIMEOUT = 5000; // 5 seconds
function makeRequest(path, method = 'GET', body = null) {
return new Promise((resolve, reject) => {
const options = {
hostname: 'localhost',
port: 3002,
path: path,
method: method,
headers: {
'Content-Type': 'application/json'
}
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
const jsonData = JSON.parse(data);
resolve({ status: res.statusCode, data: jsonData });
} catch (error) {
resolve({ status: res.statusCode, data: data });
}
});
});
req.on('error', (error) => {
reject(error);
});
req.setTimeout(TIMEOUT, () => {
req.destroy();
reject(new Error('Request timeout'));
});
if (body) {
req.write(JSON.stringify(body));
}
req.end();
});
}
async function testEndpoint(name, testFn) {
try {
console.log(`🧪 Testing ${name}...`);
const result = await testFn();
console.log(`${name}: PASS`);
return { name, status: 'PASS', result };
} catch (error) {
console.log(`${name}: FAIL - ${error.message}`);
return { name, status: 'FAIL', error: error.message };
}
}
async function runTests() {
console.log('🚀 SPORE UI Mock Server Integration Tests');
console.log('==========================================');
console.log('');
const results = [];
// Test 1: Health Check
results.push(await testEndpoint('Health Check', async () => {
const response = await makeRequest('/api/health');
if (response.status !== 200) {
throw new Error(`Expected status 200, got ${response.status}`);
}
if (!response.data.status) {
throw new Error('Missing status field');
}
if (!response.data.mock) {
throw new Error('Missing mock field');
}
return response.data;
}));
// Test 2: Discovery Nodes
results.push(await testEndpoint('Discovery Nodes', async () => {
const response = await makeRequest('/api/discovery/nodes');
if (response.status !== 200) {
throw new Error(`Expected status 200, got ${response.status}`);
}
if (!response.data.primaryNode) {
throw new Error('Missing primaryNode field');
}
if (!Array.isArray(response.data.nodes)) {
throw new Error('Nodes should be an array');
}
return response.data;
}));
// Test 3: Task Status
results.push(await testEndpoint('Task Status', async () => {
const response = await makeRequest('/api/tasks/status');
if (response.status !== 200) {
throw new Error(`Expected status 200, got ${response.status}`);
}
if (!response.data.summary) {
throw new Error('Missing summary field');
}
if (!Array.isArray(response.data.tasks)) {
throw new Error('Tasks should be an array');
}
return response.data;
}));
// Test 4: Task Control
results.push(await testEndpoint('Task Control', async () => {
const response = await makeRequest('/api/tasks/control', 'POST', {
task: 'heartbeat',
action: 'status'
});
if (response.status !== 200) {
throw new Error(`Expected status 200, got ${response.status}`);
}
if (!response.data.success) {
throw new Error('Task control should succeed');
}
return response.data;
}));
// Test 5: System Status
results.push(await testEndpoint('System Status', async () => {
const response = await makeRequest('/api/node/status');
if (response.status !== 200) {
throw new Error(`Expected status 200, got ${response.status}`);
}
if (typeof response.data.freeHeap !== 'number') {
throw new Error('freeHeap should be a number');
}
if (!response.data.chipId) {
throw new Error('Missing chipId field');
}
return response.data;
}));
// Test 6: Cluster Members
results.push(await testEndpoint('Cluster Members', async () => {
const response = await makeRequest('/api/cluster/members');
if (response.status !== 200) {
throw new Error(`Expected status 200, got ${response.status}`);
}
if (!Array.isArray(response.data.members)) {
throw new Error('Members should be an array');
}
return response.data;
}));
// Test 7: Random Primary Selection
results.push(await testEndpoint('Random Primary Selection', async () => {
const response = await makeRequest('/api/discovery/random-primary', 'POST', {
timestamp: new Date().toISOString()
});
if (response.status !== 200) {
throw new Error(`Expected status 200, got ${response.status}`);
}
if (!response.data.success) {
throw new Error('Random selection should succeed');
}
return response.data;
}));
// Test 8: Proxy Call
results.push(await testEndpoint('Proxy Call', async () => {
const response = await makeRequest('/api/proxy-call', 'POST', {
ip: '192.168.1.100',
method: 'GET',
uri: '/api/node/status'
});
if (response.status !== 200) {
throw new Error(`Expected status 200, got ${response.status}`);
}
return response.data;
}));
// Test 9: Error Handling
results.push(await testEndpoint('Error Handling', async () => {
const response = await makeRequest('/api/tasks/control', 'POST', {
task: 'nonexistent',
action: 'status'
});
if (response.status !== 404) {
throw new Error(`Expected status 404, got ${response.status}`);
}
return response.data;
}));
// Test 10: Invalid Parameters
results.push(await testEndpoint('Invalid Parameters', async () => {
const response = await makeRequest('/api/tasks/control', 'POST', {
// Missing required fields
});
if (response.status !== 400) {
throw new Error(`Expected status 400, got ${response.status}`);
}
return response.data;
}));
// Print Results
console.log('');
console.log('📊 Test Results');
console.log('===============');
const passed = results.filter(r => r.status === 'PASS').length;
const failed = results.filter(r => r.status === 'FAIL').length;
const total = results.length;
results.forEach(result => {
const status = result.status === 'PASS' ? '✅' : '❌';
console.log(`${status} ${result.name}`);
if (result.status === 'FAIL') {
console.log(` Error: ${result.error}`);
}
});
console.log('');
console.log(`Total: ${total} | Passed: ${passed} | Failed: ${failed}`);
if (failed === 0) {
console.log('');
console.log('🎉 All tests passed! Mock server is working correctly.');
} else {
console.log('');
console.log('⚠️ Some tests failed. Check the mock server configuration.');
}
return failed === 0;
}
// Check if mock server is running
async function checkMockServer() {
try {
const response = await makeRequest('/api/health');
return response.status === 200;
} catch (error) {
return false;
}
}
async function main() {
console.log('🔍 Checking if mock server is running...');
const isRunning = await checkMockServer();
if (!isRunning) {
console.log('❌ Mock server is not running!');
console.log('');
console.log('Please start the mock server first:');
console.log(' npm run mock:healthy');
console.log('');
process.exit(1);
}
console.log('✅ Mock server is running');
console.log('');
const success = await runTests();
process.exit(success ? 0 : 1);
}
// Run tests
if (require.main === module) {
main().catch(error => {
console.error('❌ Test runner failed:', error.message);
process.exit(1);
});
}
module.exports = { runTests, checkMockServer };