#!/bin/bash # ROA2WEB Ultrathin Monolith - Comprehensive Test Script # Tests all 14 acceptance criteria from the specification set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' # No Color # Test results TESTS_PASSED=0 TESTS_FAILED=0 TESTS_TOTAL=0 # Function to print test header test_header() { echo "" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${CYAN}TEST $(($TESTS_TOTAL + 1)): $1${NC}" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" } # Function to check test result check_test() { TESTS_TOTAL=$((TESTS_TOTAL + 1)) if [ $1 -eq 0 ]; then echo -e "${GREEN}✅ PASS${NC}" TESTS_PASSED=$((TESTS_PASSED + 1)) return 0 else echo -e "${RED}❌ FAIL${NC}" TESTS_FAILED=$((TESTS_FAILED + 1)) return 1 fi } # Function to check if port is in use check_port() { lsof -Pi :$1 -sTCP:LISTEN -t >/dev/null 2>&1 } echo -e "${CYAN}╔══════════════════════════════════════════════════════════╗${NC}" echo -e "${CYAN}║ ROA2WEB ULTRATHIN MONOLITH - COMPREHENSIVE TEST SUITE ║${NC}" echo -e "${CYAN}╚══════════════════════════════════════════════════════════╝${NC}" echo "" # ============================================================================ # TEST 1: Single command startup # ============================================================================ test_header "Single command startup (python backend/main.py)" echo "This test verifies that the backend can be started with a single command." echo "Checking if backend/main.py exists..." if [ -f "backend/main.py" ]; then echo "✓ backend/main.py found" check_test 0 else echo "✗ backend/main.py not found" check_test 1 fi # ============================================================================ # TEST 2: Port 8000 availability # ============================================================================ test_header "Unified backend running on port 8000" echo "Checking if backend is running on port 8000..." if check_port 8000; then echo "✓ Backend is running on port 8000" check_test 0 else echo "✗ Backend is NOT running on port 8000" echo "Please start the backend with: ./start-dev-unified.sh" check_test 1 fi # ============================================================================ # TEST 3: Health endpoint # ============================================================================ test_header "Health endpoint responds correctly" if check_port 8000; then echo "Testing: GET http://localhost:8000/health" health_response=$(curl -s http://localhost:8000/health) echo "Response:" echo "$health_response" | python3 -m json.tool if echo "$health_response" | grep -q "api"; then echo "✓ Health endpoint returns valid JSON with api status" check_test 0 else echo "✗ Health endpoint does not return expected format" check_test 1 fi else echo "✗ Backend not running (skipping test)" check_test 1 fi # ============================================================================ # TEST 4: Module status in health check # ============================================================================ test_header "Health check shows all module statuses" if check_port 8000; then health_response=$(curl -s http://localhost:8000/health) echo "Checking for module statuses in health response..." modules_ok=true for module in "oracle" "reports_cache" "data_entry_db" "telegram_bot"; do if echo "$health_response" | grep -q "$module"; then echo "✓ Module '$module' status present" else echo "✗ Module '$module' status missing" modules_ok=false fi done if $modules_ok; then check_test 0 else check_test 1 fi else echo "✗ Backend not running (skipping test)" check_test 1 fi # ============================================================================ # TEST 5: Reports module endpoints # ============================================================================ test_header "Reports module endpoints accessible" if check_port 8000; then echo "Testing Reports endpoints..." # Test /api/reports/cache/status (usually accessible without auth) reports_test=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/api/reports/cache/status) echo "GET /api/reports/cache/status → HTTP $reports_test" # Accept 200 (OK) or 401 (Unauthorized - means endpoint exists but needs auth) if [ "$reports_test" = "200" ] || [ "$reports_test" = "401" ]; then echo "✓ Reports module endpoint reachable" check_test 0 else echo "✗ Reports module endpoint not working (HTTP $reports_test)" check_test 1 fi else echo "✗ Backend not running (skipping test)" check_test 1 fi # ============================================================================ # TEST 6: Data Entry module endpoints # ============================================================================ test_header "Data Entry module endpoints accessible" if check_port 8000; then echo "Testing Data Entry endpoints..." # Test /api/data-entry/receipts (will need auth) data_entry_test=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/api/data-entry/receipts) echo "GET /api/data-entry/receipts → HTTP $data_entry_test" # Accept 200 (OK), 401 (Unauthorized), or 422 (Validation error - endpoint exists) if [ "$data_entry_test" = "200" ] || [ "$data_entry_test" = "401" ] || [ "$data_entry_test" = "422" ]; then echo "✓ Data Entry module endpoint reachable" check_test 0 else echo "✗ Data Entry module endpoint not working (HTTP $data_entry_test)" check_test 1 fi else echo "✗ Backend not running (skipping test)" check_test 1 fi # ============================================================================ # TEST 7: Telegram module endpoints # ============================================================================ test_header "Telegram module endpoints accessible" if check_port 8000; then echo "Testing Telegram endpoints..." # Test /api/telegram/auth/verify-user (should be in excluded paths) telegram_test=$(curl -s -X POST -H "Content-Type: application/json" \ -d '{"telegram_id":123}' \ -o /dev/null -w "%{http_code}" \ http://localhost:8000/api/telegram/auth/verify-user) echo "POST /api/telegram/auth/verify-user → HTTP $telegram_test" # Accept 200, 404 (not found in DB), 422 (validation error) if [ "$telegram_test" = "200" ] || [ "$telegram_test" = "404" ] || [ "$telegram_test" = "422" ]; then echo "✓ Telegram module endpoint reachable" check_test 0 else echo "✗ Telegram module endpoint not working (HTTP $telegram_test)" check_test 1 fi else echo "✗ Backend not running (skipping test)" check_test 1 fi # ============================================================================ # TEST 8: Auth endpoint (shared) # ============================================================================ test_header "Auth endpoint accessible (shared module)" if check_port 8000; then echo "Testing Auth endpoint..." # Test /api/auth/login (should return 422 without credentials) auth_test=$(curl -s -X POST -H "Content-Type: application/json" \ -o /dev/null -w "%{http_code}" \ http://localhost:8000/api/auth/login) echo "POST /api/auth/login (no body) → HTTP $auth_test" # Should return 422 (validation error - missing credentials) if [ "$auth_test" = "422" ]; then echo "✓ Auth endpoint reachable and validates input" check_test 0 else echo "✗ Auth endpoint unexpected response (HTTP $auth_test)" check_test 1 fi else echo "✗ Backend not running (skipping test)" check_test 1 fi # ============================================================================ # TEST 9: Companies endpoint (shared) # ============================================================================ test_header "Companies endpoint accessible (shared module)" if check_port 8000; then echo "Testing Companies endpoint..." # Test /api/companies (needs auth) companies_test=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/api/companies) echo "GET /api/companies → HTTP $companies_test" # Should return 401 (unauthorized - needs JWT) if [ "$companies_test" = "401" ]; then echo "✓ Companies endpoint reachable and protected by auth" check_test 0 else echo "✗ Companies endpoint unexpected response (HTTP $companies_test)" check_test 1 fi else echo "✗ Backend not running (skipping test)" check_test 1 fi # ============================================================================ # TEST 10: API documentation available # ============================================================================ test_header "API documentation accessible at /docs" if check_port 8000; then echo "Testing /docs endpoint..." docs_test=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/docs) echo "GET /docs → HTTP $docs_test" if [ "$docs_test" = "200" ]; then echo "✓ API documentation available at http://localhost:8000/docs" check_test 0 else echo "✗ API documentation not accessible (HTTP $docs_test)" check_test 1 fi else echo "✗ Backend not running (skipping test)" check_test 1 fi # ============================================================================ # TEST 11: Configuration files exist # ============================================================================ test_header "Configuration files properly set up" echo "Checking configuration files..." config_ok=true if [ -f "backend/config.py" ]; then echo "✓ backend/config.py exists" else echo "✗ backend/config.py missing" config_ok=false fi if [ -f "backend/requirements.txt" ]; then echo "✓ backend/requirements.txt exists" else echo "✗ backend/requirements.txt missing" config_ok=false fi if [ -f "backend/.env.example" ]; then echo "✓ backend/.env.example exists" else echo "✗ backend/.env.example missing" config_ok=false fi if $config_ok; then check_test 0 else check_test 1 fi # ============================================================================ # TEST 12: Module router factories exist # ============================================================================ test_header "Module router factories properly created" echo "Checking router factory files..." routers_ok=true for module in "reports" "data-entry" "telegram"; do router_file="backend/modules/${module}/routers/__init__.py" if [ -f "$router_file" ]; then echo "✓ ${module} router factory exists" # Check for factory function if grep -q "create_.*_router" "$router_file"; then echo " ✓ Factory function found" else echo " ✗ Factory function missing" routers_ok=false fi else echo "✗ ${module} router factory missing" routers_ok=false fi done if $routers_ok; then check_test 0 else check_test 1 fi # ============================================================================ # TEST 13: Frontend proxy configured # ============================================================================ test_header "Frontend proxy configured to use port 8000" echo "Checking vite.config.js..." if [ -f "vite.config.js" ]; then echo "✓ vite.config.js exists" if grep -q "localhost:8000" vite.config.js; then echo "✓ Proxy configured for port 8000" check_test 0 else echo "✗ Proxy not configured for port 8000" check_test 1 fi else echo "✗ vite.config.js not found" check_test 1 fi # ============================================================================ # TEST 14: Startup scripts created # ============================================================================ test_header "New startup scripts created" echo "Checking startup scripts..." scripts_ok=true for script in "start-backend.sh" "start-frontend.sh" "start-prod.sh" "start-test.sh" "status.sh"; do if [ -f "$script" ] && [ -x "$script" ]; then echo "✓ $script exists and is executable" else echo "✗ $script missing or not executable" scripts_ok=false fi done if $scripts_ok; then check_test 0 else check_test 1 fi # ============================================================================ # SUMMARY # ============================================================================ echo "" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${CYAN}TEST SUMMARY${NC}" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo "" echo -e "Total Tests: ${BLUE}${TESTS_TOTAL}${NC}" echo -e "Passed: ${GREEN}${TESTS_PASSED}${NC}" echo -e "Failed: ${RED}${TESTS_FAILED}${NC}" echo "" if [ $TESTS_FAILED -eq 0 ]; then echo -e "${GREEN}╔══════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}║ ✅ ALL TESTS PASSED! IMPLEMENTATION COMPLETE! ✅ ║${NC}" echo -e "${GREEN}╚══════════════════════════════════════════════════════╝${NC}" exit 0 else echo -e "${YELLOW}╔══════════════════════════════════════════════════════╗${NC}" echo -e "${YELLOW}║ ⚠️ SOME TESTS FAILED - REVIEW REQUIRED ⚠️ ║${NC}" echo -e "${YELLOW}╚══════════════════════════════════════════════════════╝${NC}" echo "" echo -e "${YELLOW}Tip: Start the backend with ./start-dev-unified.sh if not running${NC}" exit 1 fi