/** * Frontend API Routing Test - Direct HTTP Testing * * This test verifies API routing by making direct HTTP requests to the frontend * and checking what URLs are actually being called. */ const https = require('https'); const http = require('http'); // Test configuration const TEST_CONFIG = { baseUrl: 'https://geeplo.com', timeout: 10000, }; /** * Make HTTP request with proper headers */ function makeRequest(url, options = {}) { return new Promise((resolve, reject) => { const isHttps = url.startsWith('https://'); const client = isHttps ? https : http; const defaultOptions = { headers: { 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', }, timeout: TEST_CONFIG.timeout, }; const requestOptions = { ...defaultOptions, ...options, hostname: new URL(url).hostname, port: new URL(url).port || (isHttps ? 443 : 80), path: new URL(url).pathname + new URL(url).search, method: options.method || 'GET', }; const req = client.request(requestOptions, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { resolve({ statusCode: res.statusCode, headers: res.headers, url: url, body: data, }); }); }); req.on('error', (err) => { reject(err); }); req.on('timeout', () => { req.destroy(); reject(new Error(`Request timeout for ${url}`)); }); if (options.body) { req.write(options.body); } req.end(); }); } /** * Test the frontend homepage to see what it loads */ async function testFrontendHomepage() { console.log('๐ŸŒ Testing frontend homepage...'); try { const response = await makeRequest(`${TEST_CONFIG.baseUrl}/juntete`); console.log(`โœ… Homepage loaded successfully`); console.log(`๐Ÿ“Š Status: ${response.statusCode}`); console.log(`๐Ÿ“ฆ Content-Type: ${response.headers['content-type']}`); // Check if the homepage contains references to API endpoints const body = response.body; const hasApiReference = body.includes('/api/trips'); const hasCorrectApiReference = body.includes('/juntete/api/trips'); console.log(`๐Ÿ” Contains /api/trips reference: ${hasApiReference}`); console.log(`๐Ÿ” Contains /juntete/api/trips reference: ${hasCorrectApiReference}`); // Look for JavaScript files const jsFileMatches = body.match(/src="([^"]*\.js[^"]*)"/g) || []; console.log(`๐Ÿ“ฆ Found ${jsFileMatches.length} JavaScript file references`); return { success: true, statusCode: response.statusCode, hasApiReference, hasCorrectApiReference, jsFiles: jsFileMatches.map(match => match.replace(/src="|"$/g, '')), }; } catch (error) { console.error(`โŒ Homepage test failed:`, error.message); return { success: false, error: error.message }; } } /** * Test API endpoints directly */ async function testApiEndpoints() { console.log('\n๐Ÿ” Testing API endpoints...'); const tests = [ { name: 'Correct API endpoint', url: `${TEST_CONFIG.baseUrl}/juntete/api/trips`, method: 'POST', body: JSON.stringify({ name: 'Test Trip', creator_name: 'Test User', currency_code: 'USD' }), headers: { 'Content-Type': 'application/json', }, }, { name: 'Incorrect API endpoint', url: `${TEST_CONFIG.baseUrl}/api/trips`, method: 'POST', body: JSON.stringify({ name: 'Test Trip', creator_name: 'Test User', currency_code: 'USD' }), headers: { 'Content-Type': 'application/json', }, }, ]; const results = []; for (const test of tests) { console.log(`\n๐Ÿ“ Testing: ${test.name}`); console.log(`๐Ÿ”— URL: ${test.url}`); try { const response = await makeRequest(test.url, { method: test.method, body: test.body, headers: test.headers, }); console.log(`๐Ÿ“Š Status: ${response.statusCode}`); console.log(`๐Ÿ“ฆ Content-Type: ${response.headers['content-type']}`); let responseInfo = { status: response.statusCode }; // Try to parse response body try { const parsed = JSON.parse(response.body); responseInfo = { ...responseInfo, data: parsed }; if (parsed.detail) { console.log(`๐Ÿ“ Response: ${parsed.detail}`); } } catch (e) { // Not JSON, that's fine console.log(`๐Ÿ“ Response length: ${response.body.length} characters`); } results.push({ name: test.name, url: test.url, success: true, response: responseInfo, }); } catch (error) { console.log(`โŒ Request failed: ${error.message}`); results.push({ name: test.name, url: test.url, success: false, error: error.message, }); } } return results; } /** * Test JavaScript bundles for API configuration */ async function testJavaScriptBundles() { console.log('\n๐Ÿ“ฆ Testing JavaScript bundles...'); try { // First get the homepage to find JS bundles const homepageResponse = await makeRequest(`${TEST_CONFIG.baseUrl}/juntete`); const body = homepageResponse.body; // Extract JavaScript file URLs const jsFileRegex = /src="([^"]*\.js[^"]*)"/g; const jsFiles = []; let match; while ((match = jsFileRegex.exec(body)) !== null) { const jsFile = match[1]; // Convert relative URLs to absolute const absoluteUrl = jsFile.startsWith('http') ? jsFile : `${TEST_CONFIG.baseUrl}${jsFile.startsWith('/') ? '' : '/'}${jsFile}`; jsFiles.push(absoluteUrl); } console.log(`๐Ÿ” Found ${jsFiles.length} JavaScript files to inspect`); const results = []; for (const jsFile of jsFiles.slice(0, 5)) { // Limit to first 5 for speed console.log(`\n๐Ÿ“ฆ Inspecting: ${jsFile.split('/').pop()}`); try { const jsResponse = await makeRequest(jsFile); const jsContent = jsResponse.body; // Look for API-related patterns const patterns = { directFetch: /fetch\s*\(\s*['"`]\/api\//g, correctApi: /fetch\s*\(\s*['"`]\/juntete\/api\//g, axiosBase: /baseURL:\s*['"`]\/juntete['"`]/g, apiImport: /from\s+['"`]@\/lib\/api['"`]/g, }; const patternMatches = {}; for (const [name, regex] of Object.entries(patterns)) { const matches = jsContent.match(regex); patternMatches[name] = matches ? matches.length : 0; } console.log(` ๐Ÿ” Direct fetch to /api: ${patternMatches.directFetch}`); console.log(` โœ… Fetch to /juntete/api: ${patternMatches.correctApi}`); console.log(` โš™๏ธ Axios baseURL config: ${patternMatches.axiosBase}`); console.log(` ๐Ÿ“ฆ API imports: ${patternMatches.apiImport}`); results.push({ file: jsFile.split('/').pop(), success: true, patterns: patternMatches, }); } catch (error) { console.log(` โŒ Failed to load: ${error.message}`); results.push({ file: jsFile.split('/').pop(), success: false, error: error.message, }); } } return results; } catch (error) { console.error(`โŒ JavaScript bundle inspection failed:`, error.message); return []; } } /** * Main test runner */ async function runApiRoutingTests() { console.log('๐Ÿงช Frontend API Routing Test'); console.log('============================\n'); // Test 1: Homepage loading const homepageResult = await testFrontendHomepage(); // Test 2: API endpoints const apiResults = await testApiEndpoints(); // Test 3: JavaScript bundles const jsResults = await testJavaScriptBundles(); // Analysis console.log('\n๐Ÿ“Š TEST ANALYSIS'); console.log('================\n'); console.log('๐Ÿ  Homepage Results:'); if (homepageResult.success) { console.log(` โœ… Loaded successfully (${homepageResult.statusCode})`); console.log(` ๐Ÿ” API references found: ${homepageResult.hasApiReference ? 'YES' : 'NO'}`); console.log(` โœ… Correct API references: ${homepageResult.hasCorrectApiReference ? 'YES' : 'NO'}`); } else { console.log(` โŒ Failed to load: ${homepageResult.error}`); } console.log('\n๐Ÿ”— API Endpoint Results:'); apiResults.forEach(result => { const status = result.success ? 'โœ…' : 'โŒ'; console.log(` ${status} ${result.name}: ${result.success ? result.response.status : result.error}`); }); console.log('\n๐Ÿ“ฆ JavaScript Bundle Results:'); jsResults.forEach(result => { const status = result.success ? 'โœ…' : 'โŒ'; console.log(` ${status} ${result.file}`); if (result.success && result.patterns) { const issues = []; if (result.patterns.directFetch > 0) issues.push('Direct /api calls'); if (result.patterns.correctApi === 0 && result.patterns.axiosBase === 0) issues.push('No correct API routing'); if (issues.length > 0) { console.log(` โš ๏ธ Issues: ${issues.join(', ')}`); } else { console.log(` โœ… No routing issues detected`); } } }); // Final verdict console.log('\n๐ŸŽฏ FINAL VERDICT'); console.log('================\n'); const correctApiWorking = apiResults.find(r => r.url.includes('/juntete/api') && r.success); const incorrectApiWorking = apiResults.find(r => r.url.includes('/api/trips') && !r.url.includes('/juntete') && r.success); const hasDirectApiCalls = jsResults.some(r => r.success && r.patterns?.directFetch > 0); if (correctApiWorking && !incorrectApiWorking && !hasDirectApiCalls) { console.log('๐ŸŽ‰ SUCCESS: Frontend is correctly routing to /juntete/api'); process.exit(0); } else { console.log('๐Ÿ’ฅ ISSUES DETECTED:'); if (!correctApiWorking) console.log(' - Correct API endpoint not working'); if (incorrectApiWorking) console.log(' - Incorrect API endpoint still accessible'); if (hasDirectApiCalls) console.log(' - JavaScript contains direct API calls'); process.exit(1); } } // Run the tests if (require.main === module) { runApiRoutingTests().catch(console.error); } module.exports = { testFrontendHomepage, testApiEndpoints, testJavaScriptBundles, runApiRoutingTests, };