275 lines
12 KiB
Bash
275 lines
12 KiB
Bash
#!/bin/bash
|
|
# RFCP Frontend-Backend Integration Test
|
|
# Tests API endpoints that frontend uses
|
|
# Usage: ./rfcp-integration-test.sh [base_url]
|
|
|
|
BASE_URL="${1:-https://api.rfcp.eliah.one}"
|
|
PASSED=0
|
|
FAILED=0
|
|
|
|
# Colors
|
|
GREEN='\033[0;32m'
|
|
RED='\033[0;31m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo " RFCP Integration Test (Frontend ↔ Backend)"
|
|
echo " Target: $BASE_URL"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
test_endpoint() {
|
|
local name="$1"
|
|
local method="$2"
|
|
local endpoint="$3"
|
|
local expected="$4"
|
|
local data="$5"
|
|
|
|
if [ "$method" == "GET" ]; then
|
|
response=$(curl -s -w "\n%{http_code}" "$BASE_URL$endpoint")
|
|
else
|
|
response=$(curl -s -w "\n%{http_code}" -X "$method" "$BASE_URL$endpoint" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$data")
|
|
fi
|
|
|
|
http_code=$(echo "$response" | tail -n1)
|
|
body=$(echo "$response" | sed '$d')
|
|
|
|
if [ "$http_code" == "200" ] && echo "$body" | grep -q "$expected"; then
|
|
echo -e "${GREEN}✓${NC} $name"
|
|
((PASSED++))
|
|
return 0
|
|
else
|
|
echo -e "${RED}✗${NC} $name (HTTP $http_code)"
|
|
echo " Expected: $expected"
|
|
echo " Got: ${body:0:100}..."
|
|
((FAILED++))
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
# Core API Tests
|
|
# ═══════════════════════════════════════════════════
|
|
echo -e "${CYAN}Core API${NC}"
|
|
echo "─────────────────────────────────────────────────"
|
|
|
|
test_endpoint "Health check" "GET" "/api/health/" '"status":"ok"'
|
|
test_endpoint "Database connection" "GET" "/api/health/db" '"database":"connected"'
|
|
test_endpoint "API version" "GET" "/" '"version"'
|
|
|
|
echo ""
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
# Project API (state persistence)
|
|
# ═══════════════════════════════════════════════════
|
|
echo -e "${CYAN}Project API${NC}"
|
|
echo "─────────────────────────────────────────────────"
|
|
|
|
test_endpoint "Get project" "GET" "/api/projects/current" '"name":"global"'
|
|
test_endpoint "Get settings" "GET" "/api/projects/current/settings" '"radius"'
|
|
|
|
# Save test site
|
|
test_endpoint "Save sites" "PUT" "/api/projects/current/sites" '"updated"' \
|
|
'[{"id":"integration-test","name":"Integration Test Site","lat":48.46,"lon":35.05,"height":30,"power":43}]'
|
|
|
|
# Verify saved
|
|
test_endpoint "Verify sites" "GET" "/api/projects/current/sites" "Integration Test Site"
|
|
|
|
echo ""
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
# Coverage API (main functionality)
|
|
# ═══════════════════════════════════════════════════
|
|
echo -e "${CYAN}Coverage API${NC}"
|
|
echo "─────────────────────────────────────────────────"
|
|
|
|
# Presets
|
|
test_endpoint "Get presets" "GET" "/api/coverage/presets" '"fast"'
|
|
|
|
# Coverage calculation
|
|
echo -n "Coverage calculation (fast)... "
|
|
start=$(date +%s)
|
|
calc_response=$(curl -s -X POST "$BASE_URL/api/coverage/calculate" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"sites": [{"lat": 48.46, "lon": 35.05, "height": 30, "power": 43, "gain": 15, "frequency": 1800}],
|
|
"settings": {"radius": 1000, "resolution": 100, "preset": "fast"}
|
|
}')
|
|
end=$(date +%s)
|
|
|
|
# Validate response structure
|
|
has_points=$(echo "$calc_response" | jq 'has("points")')
|
|
has_stats=$(echo "$calc_response" | jq 'has("stats")')
|
|
has_time=$(echo "$calc_response" | jq 'has("computation_time")')
|
|
has_models=$(echo "$calc_response" | jq 'has("models_used")')
|
|
point_count=$(echo "$calc_response" | jq '.count')
|
|
|
|
if [ "$has_points" == "true" ] && [ "$has_stats" == "true" ] && [ "$has_time" == "true" ] && [ "$has_models" == "true" ] && [ "$point_count" -gt 0 ]; then
|
|
echo -e "${GREEN}✓${NC} Coverage calculation ($point_count points, $((end-start))s)"
|
|
((PASSED++))
|
|
else
|
|
echo -e "${RED}✗${NC} Coverage calculation - missing fields or no points"
|
|
((FAILED++))
|
|
fi
|
|
|
|
# Response structure check
|
|
echo -n "Response structure... "
|
|
min_rsrp=$(echo "$calc_response" | jq '.stats.min_rsrp')
|
|
max_rsrp=$(echo "$calc_response" | jq '.stats.max_rsrp')
|
|
models=$(echo "$calc_response" | jq -r '.models_used[]' | head -1)
|
|
|
|
if [ "$min_rsrp" != "null" ] && [ "$max_rsrp" != "null" ] && [ -n "$models" ]; then
|
|
echo -e "${GREEN}✓${NC} Response structure valid"
|
|
echo " RSRP: $min_rsrp to $max_rsrp dBm"
|
|
echo " Models: $(echo "$calc_response" | jq -r '.models_used | join(", ")')"
|
|
((PASSED++))
|
|
else
|
|
echo -e "${RED}✗${NC} Invalid response structure"
|
|
((FAILED++))
|
|
fi
|
|
|
|
# Buildings endpoint
|
|
test_endpoint "Get buildings" "GET" "/api/coverage/buildings?min_lat=48.455&min_lon=35.045&max_lat=48.465&max_lon=35.055" '"count"'
|
|
|
|
echo ""
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
# Terrain API
|
|
# ═══════════════════════════════════════════════════
|
|
echo -e "${CYAN}Terrain API${NC}"
|
|
echo "─────────────────────────────────────────────────"
|
|
|
|
test_endpoint "Get elevation" "GET" "/api/terrain/elevation?lat=48.46&lon=35.05" '"elevation"'
|
|
|
|
# Elevation profile
|
|
echo -n "Elevation profile... "
|
|
profile_response=$(curl -s "$BASE_URL/api/terrain/profile?lat1=48.46&lon1=35.05&lat2=48.47&lon2=35.06&points=10")
|
|
profile_count=$(echo "$profile_response" | jq '.profile | length')
|
|
|
|
if [ "$profile_count" -eq 10 ]; then
|
|
echo -e "${GREEN}✓${NC} Elevation profile ($profile_count points)"
|
|
((PASSED++))
|
|
else
|
|
echo -e "${RED}✗${NC} Elevation profile (expected 10, got $profile_count)"
|
|
((FAILED++))
|
|
fi
|
|
|
|
# LoS check
|
|
test_endpoint "Line of Sight" "GET" "/api/terrain/los?tx_lat=48.46&tx_lon=35.05&tx_height=30&rx_lat=48.47&rx_lon=35.06" '"has_los"'
|
|
|
|
# Fresnel check
|
|
test_endpoint "Fresnel clearance" "GET" "/api/terrain/fresnel?tx_lat=48.46&tx_lon=35.05&tx_height=30&rx_lat=48.47&rx_lon=35.06&rx_height=1.5&frequency=1800" '"clearance_percent"'
|
|
|
|
echo ""
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
# Error Handling
|
|
# ═══════════════════════════════════════════════════
|
|
echo -e "${CYAN}Error Handling${NC}"
|
|
echo "─────────────────────────────────────────────────"
|
|
|
|
# Invalid coordinates
|
|
echo -n "Invalid coordinates... "
|
|
error_response=$(curl -s -o /dev/null -w "%{http_code}" "$BASE_URL/api/terrain/elevation?lat=999&lon=999")
|
|
if [ "$error_response" == "422" ] || [ "$error_response" == "400" ]; then
|
|
echo -e "${GREEN}✓${NC} Returns error for invalid coords (HTTP $error_response)"
|
|
((PASSED++))
|
|
else
|
|
echo -e "${YELLOW}⚠${NC} Unexpected response: HTTP $error_response"
|
|
fi
|
|
|
|
# Empty sites
|
|
echo -n "Empty sites array... "
|
|
empty_response=$(curl -s -X POST "$BASE_URL/api/coverage/calculate" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"sites": [], "settings": {"radius": 1000, "resolution": 100}}')
|
|
empty_code=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$BASE_URL/api/coverage/calculate" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"sites": [], "settings": {"radius": 1000, "resolution": 100}}')
|
|
|
|
if [ "$empty_code" == "400" ]; then
|
|
echo -e "${GREEN}✓${NC} Rejects empty sites (HTTP 400)"
|
|
((PASSED++))
|
|
else
|
|
echo -e "${YELLOW}⚠${NC} Should reject empty sites (got HTTP $empty_code)"
|
|
fi
|
|
|
|
# Too large radius
|
|
echo -n "Radius limit... "
|
|
large_response=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$BASE_URL/api/coverage/calculate" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"sites": [{"lat": 48.46, "lon": 35.05, "height": 30, "power": 43, "gain": 15, "frequency": 1800}], "settings": {"radius": 100000, "resolution": 100}}')
|
|
|
|
if [ "$large_response" == "400" ]; then
|
|
echo -e "${GREEN}✓${NC} Rejects >50km radius (HTTP 400)"
|
|
((PASSED++))
|
|
else
|
|
echo -e "${YELLOW}⚠${NC} Should limit radius (got HTTP $large_response)"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
# Performance Check
|
|
# ═══════════════════════════════════════════════════
|
|
echo -e "${CYAN}Performance${NC}"
|
|
echo "─────────────────────────────────────────────────"
|
|
|
|
echo -n "Fast preset timing... "
|
|
start=$(date +%s.%N)
|
|
curl -s -X POST "$BASE_URL/api/coverage/calculate" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"sites": [{"lat": 48.46, "lon": 35.05, "height": 30, "power": 43, "gain": 15, "frequency": 1800}], "settings": {"radius": 2000, "resolution": 100, "preset": "fast"}}' > /dev/null
|
|
end=$(date +%s.%N)
|
|
duration=$(echo "$end - $start" | bc)
|
|
|
|
if (( $(echo "$duration < 5" | bc -l) )); then
|
|
echo -e "${GREEN}✓${NC} Fast preset: ${duration}s (< 5s)"
|
|
((PASSED++))
|
|
else
|
|
echo -e "${YELLOW}⚠${NC} Fast preset slow: ${duration}s (expected < 5s)"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
# Swagger/Docs
|
|
# ═══════════════════════════════════════════════════
|
|
echo -e "${CYAN}Documentation${NC}"
|
|
echo "─────────────────────────────────────────────────"
|
|
|
|
swagger_code=$(curl -s -o /dev/null -w "%{http_code}" "$BASE_URL/docs")
|
|
if [ "$swagger_code" == "200" ]; then
|
|
echo -e "${GREEN}✓${NC} Swagger UI accessible"
|
|
((PASSED++))
|
|
else
|
|
echo -e "${RED}✗${NC} Swagger UI (HTTP $swagger_code)"
|
|
((FAILED++))
|
|
fi
|
|
|
|
test_endpoint "OpenAPI schema" "GET" "/openapi.json" '"openapi"'
|
|
|
|
echo ""
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
# Summary
|
|
# ═══════════════════════════════════════════════════
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
TOTAL=$((PASSED + FAILED))
|
|
if [ $FAILED -eq 0 ]; then
|
|
echo -e " ${GREEN}All tests passed!${NC} ($PASSED/$TOTAL)"
|
|
echo ""
|
|
echo " Frontend can safely integrate with this backend."
|
|
else
|
|
echo -e " ${YELLOW}Results:${NC} ${GREEN}$PASSED passed${NC}, ${RED}$FAILED failed${NC}"
|
|
echo ""
|
|
echo " Fix failing tests before frontend integration."
|
|
fi
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
exit $FAILED
|