Files
service-finder/backend/scripts/test_vehicle_registration.py
2026-06-04 07:26:22 +00:00

160 lines
5.6 KiB
Python

#!/usr/bin/env python3
"""
Authenticated E2E test for vehicle registration endpoint.
Reads credentials from backend/tests/test_credentials.json,
authenticates via /api/v1/auth/login, obtains JWT token,
and tests POST /api/v1/assets/vehicles endpoint.
"""
import json
import sys
import os
import asyncio
import aiohttp
import logging
from typing import Dict, Any
# Add parent directory to path to import app modules if needed
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
CREDENTIALS_PATH = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
"tests",
"test_credentials.json"
)
async def load_credentials() -> Dict[str, Any]:
"""Load test credentials from JSON file."""
try:
with open(CREDENTIALS_PATH, 'r') as f:
creds = json.load(f)
logger.info(f"Loaded credentials for {creds.get('email')}")
return creds
except FileNotFoundError:
logger.error(f"Credentials file not found at {CREDENTIALS_PATH}")
sys.exit(1)
except json.JSONDecodeError as e:
logger.error(f"Invalid JSON in credentials file: {e}")
sys.exit(1)
async def authenticate(session: aiohttp.ClientSession, base_url: str, email: str, password: str) -> str:
"""Authenticate and return JWT token."""
login_url = f"{base_url}/api/v1/auth/login"
# Use form data as required by OAuth2PasswordRequestForm
form_data = aiohttp.FormData()
form_data.add_field('username', email)
form_data.add_field('password', password)
try:
async with session.post(login_url, data=form_data) as resp:
if resp.status != 200:
text = await resp.text()
logger.error(f"Authentication failed: {resp.status} - {text}")
raise ValueError(f"Authentication failed: {resp.status}")
data = await resp.json()
token = data.get("access_token")
if not token:
logger.error(f"No access_token in response: {data}")
raise ValueError("No access_token in response")
logger.info("Authentication successful")
return token
except aiohttp.ClientError as e:
logger.error(f"Network error during authentication: {e}")
raise
async def test_vehicle_creation(session: aiohttp.ClientSession, base_url: str, token: str):
"""Test POST /api/v1/assets/vehicles endpoint."""
url = f"{base_url}/api/v1/assets/vehicles"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
# Realistic payload with valid catalog_id and required fields
payload = {
"vin": "TESTVIN1234567890",
"license_plate": "TEST-001",
"catalog_id": 5, # Valid catalog_id from database
"brand": "BMW",
"model": "X5",
"vehicle_class": "car",
"fuel_type": "petrol",
"engine_capacity": 3000,
"power_kw": 200,
"transmission_type": "automatic",
"drive_type": "awd"
}
logger.info(f"Testing vehicle creation with payload: {payload}")
try:
async with session.post(url, json=payload, headers=headers) as resp:
status = resp.status
text = await resp.text()
logger.info(f"Response status: {status}")
logger.info(f"Response body: {text}")
if status == 201:
logger.info("✅ Vehicle creation test PASSED")
return True
elif status == 404:
logger.error("❌ Endpoint not found (404). Check API route.")
return False
elif status == 400:
logger.warning("⚠️ Bad request (400). Might be due to missing catalog_id or validation.")
# Try to parse error details
try:
error_data = json.loads(text)
logger.warning(f"Error details: {error_data}")
except:
pass
return False
elif status == 500:
logger.error("❌ Internal server error (500). Check server logs.")
# Try to parse error details
try:
error_data = json.loads(text)
logger.error(f"Error details: {error_data}")
except:
pass
return False
else:
logger.error(f"❌ Unexpected status: {status}")
return False
except aiohttp.ClientError as e:
logger.error(f"Network error during vehicle creation: {e}")
return False
async def main():
"""Main test execution."""
logger.info("Starting authenticated E2E test for vehicle registration")
# Load credentials
creds = await load_credentials()
base_url = creds.get("base_url", "http://localhost:8000")
email = creds["email"]
password = creds["password"]
# Create aiohttp session
async with aiohttp.ClientSession() as session:
# Authenticate
try:
token = await authenticate(session, base_url, email, password)
except Exception as e:
logger.error(f"Authentication failed: {e}")
sys.exit(1)
# Test vehicle creation
success = await test_vehicle_creation(session, base_url, token)
if success:
logger.info("🎉 All tests passed!")
sys.exit(0)
else:
logger.error("💥 Test failed!")
sys.exit(1)
if __name__ == "__main__":
asyncio.run(main())