agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
212 lines (177 loc) • 7.18 kB
JavaScript
// Test file for Frontend-Backend integration analysis utilities
// 🔗 Tests: analyzeProjectIntegration → extractBackendEndpoints → extractFrontendCalls → detectMissingEndpoints
const {
analyzeProjectIntegration,
extractBackendEndpoints,
extractFrontendCalls,
detectMissingEndpoints,
detectUnusedEndpoints,
normalizeRoute
} = require('./analyzeFrontendBackend');
const fs = require('fs');
const path = require('path');
/**
* Test runner for Frontend-Backend integration analysis
*/
async function runTests() {
console.log('=== Testing Frontend-Backend Integration Analysis Utilities ===');
const results = {
total: 0,
passed: 0
};
// Test route normalization
results.total++;
try {
const testRoutes = [
{ input: '/api/users/', expected: '/api/users' },
{ input: '/api/users?page=1', expected: '/api/users' },
{ input: '/API/Users/:id', expected: '/api/users/:param' },
{ input: '/api/posts', expected: '/api/posts' }
];
let allPassed = true;
testRoutes.forEach(({ input, expected }) => {
const result = normalizeRoute(input);
if (result !== expected) {
console.log(`✗ normalizeRoute failed: ${input} -> ${result}, expected ${expected}`);
allPassed = false;
}
});
if (allPassed) {
console.log('✓ normalizeRoute correctly normalizes various route formats');
results.passed++;
}
} catch (error) {
console.log(`✗ normalizeRoute failed: ${error.message}`);
}
// Test backend endpoint extraction
results.total++;
try {
const backendContent = `
const express = require('express');
const app = express();
app.get('/api/users', (req, res) => {
res.json({ users: [] });
});
app.post('/api/users', (req, res) => {
res.status(201).json({ user: req.body });
});
router.delete('/api/users/:id', (req, res) => {
res.status(204).send();
});
`;
// Create temporary backend file
const tempBackendFile = path.join(__dirname, 'temp-backend.js');
fs.writeFileSync(tempBackendFile, backendContent);
const endpoints = await extractBackendEndpoints([tempBackendFile]);
// Clean up
fs.unlinkSync(tempBackendFile);
if (Array.isArray(endpoints) && endpoints.length >= 3) {
const hasGetUsers = endpoints.some(e => e.method === 'GET' && e.route.includes('/api/users'));
const hasPostUsers = endpoints.some(e => e.method === 'POST' && e.route.includes('/api/users'));
const hasDeleteUsers = endpoints.some(e => e.method === 'DELETE' && e.route.includes('/api/users'));
if (hasGetUsers && hasPostUsers && hasDeleteUsers) {
console.log('✓ extractBackendEndpoints correctly identifies Express.js routes');
results.passed++;
} else {
console.log('✗ extractBackendEndpoints failed - missing expected endpoints');
}
} else {
console.log('✗ extractBackendEndpoints failed - insufficient endpoints found');
}
} catch (error) {
console.log(`✗ extractBackendEndpoints failed: ${error.message}`);
}
// Test frontend call extraction
results.total++;
try {
const frontendContent = `
import axios from 'axios';
const UserService = {
getUsers: () => {
return fetch('/api/users');
},
createUser: (userData) => {
return axios.post('/api/users', userData);
},
deleteUser: (id) => {
return axios.delete(\`/api/users/\${id}\`);
},
getProfile: () => {
return fetch('/api/profile', { method: 'GET' });
}
};
`;
// Create temporary frontend file
const tempFrontendFile = path.join(__dirname, 'temp-frontend.js');
fs.writeFileSync(tempFrontendFile, frontendContent);
const calls = await extractFrontendCalls([tempFrontendFile]);
// Clean up
fs.unlinkSync(tempFrontendFile);
if (Array.isArray(calls) && calls.length >= 3) {
const hasFetchUsers = calls.some(c => c.route.includes('/api/users') && c.type === 'fetch');
const hasAxiosPost = calls.some(c => c.method === 'POST' && c.type === 'axios');
const hasAxiosDelete = calls.some(c => c.method === 'DELETE' && c.type === 'axios');
if (hasFetchUsers && hasAxiosPost && hasAxiosDelete) {
console.log('✓ extractFrontendCalls correctly identifies fetch and axios calls');
results.passed++;
} else {
console.log('✗ extractFrontendCalls failed - missing expected calls');
console.log(' Found calls:', calls.length);
console.log(' Has fetch users:', hasFetchUsers);
console.log(' Has axios post:', hasAxiosPost);
console.log(' Has axios delete:', hasAxiosDelete);
calls.forEach(c => console.log(' Call:', c.type, c.method, c.route));
}
} else {
console.log('✗ extractFrontendCalls failed - insufficient calls found');
console.log(' Found calls:', calls ? calls.length : 'undefined');
}
} catch (error) {
console.log(`✗ extractFrontendCalls failed: ${error.message}`);
}
// Test integration analysis
results.total++;
try {
// Create temporary project structure
const tempDir = path.join(__dirname, 'temp-project');
const frontendDir = path.join(tempDir, 'frontend');
const backendDir = path.join(tempDir, 'backend');
fs.mkdirSync(tempDir, { recursive: true });
fs.mkdirSync(frontendDir, { recursive: true });
fs.mkdirSync(backendDir, { recursive: true });
// Create backend file
const backendContent = `
app.get('/api/users', handler);
app.post('/api/posts', handler);
`;
fs.writeFileSync(path.join(backendDir, 'routes.js'), backendContent);
// Create frontend file with missing endpoint call
const frontendContent = `
fetch('/api/users');
axios.post('/api/comments', data);
`;
fs.writeFileSync(path.join(frontendDir, 'api.js'), frontendContent);
const analysis = await analyzeProjectIntegration(tempDir);
// Clean up
fs.rmSync(tempDir, { recursive: true, force: true });
if (analysis &&
analysis.summary &&
typeof analysis.summary.integrationScore === 'number' &&
Array.isArray(analysis.issues) &&
Array.isArray(analysis.endpoints) &&
Array.isArray(analysis.calls) &&
Array.isArray(analysis.recommendations)) {
console.log('✓ analyzeProjectIntegration returns valid integration analysis');
results.passed++;
} else {
console.log('✗ analyzeProjectIntegration failed - invalid structure');
}
} catch (error) {
console.log(`✗ analyzeProjectIntegration failed: ${error.message}`);
}
console.log(`=== Frontend-Backend Integration Test Results ===`);
console.log(`Tests passed: ${results.passed}/${results.total}`);
console.log(`Success rate: ${((results.passed / results.total) * 100).toFixed(1)}%`);
return results;
}
module.exports = { runTests };