import asyncio import httpx from sqlalchemy import select, delete from app.db.session import AsyncSessionLocal from app.models.identity import User, Person from app.models.marketplace.organization import Organization, Branch, OrganizationMember from app.models.vehicle.asset import Asset from app.models.vehicle.vehicle_definitions import VehicleModelDefinition from app.core.security import create_tokens import uuid async def setup_test_data(): async with AsyncSessionLocal() as db: # 1. Clean previous test data await db.execute(delete(Asset).where(Asset.license_plate.in_(["TEST-123", "DRAFT-456", "OTHER-123"]))) await db.execute(delete(VehicleModelDefinition).where(VehicleModelDefinition.make == "Ford", VehicleModelDefinition.marketing_name == "Focus")) await db.execute(delete(Branch).where(Branch.name == "Test Main Branch")) await db.execute(delete(OrganizationMember)) await db.execute(delete(Organization).where(Organization.name == "Test Org")) test_users = await db.execute(select(User).where(User.email.in_(["test1@test.com", "test2@test.com"]))) for u in test_users.scalars().all(): await db.execute(delete(User).where(User.id == u.id)) await db.commit() # 2. Create Person person1 = Person(first_name="Test1", last_name="User1") person2 = Person(first_name="Test2", last_name="User2") db.add_all([person1, person2]) await db.flush() # 3. Create Users user1 = User(email="test1@test.com", hashed_password="pw", is_active=True, person_id=person1.id, subscription_plan="personal", is_vip=False, preferred_language="en", region_code="HU", preferred_currency="EUR", scope_level="personal", is_vip=False, preferred_language="en", region_code="HU", preferred_currency="EUR") user2 = User(email="test2@test.com", hashed_password="pw", is_active=True, person_id=person2.id, subscription_plan="personal", is_vip=False, preferred_language="en", region_code="HU", preferred_currency="EUR", scope_level="personal", is_vip=False, preferred_language="en", region_code="HU", preferred_currency="EUR") db.add_all([user1, user2]) await db.flush() # 4. Create Organization & Branch org = Organization(name="Test Org", tax_number="123456") db.add(org) await db.flush() member1 = OrganizationMember(organization_id=org.id, user_id=user1.id, role="owner") member2 = OrganizationMember(organization_id=org.id, user_id=user2.id, role="member") db.add_all([member1, member2]) branch = Branch(organization_id=org.id, name="Test Main Branch", is_main=True) db.add(branch) # 5. Create VehicleModelDefinition model_def = VehicleModelDefinition( make="Ford", marketing_name="Focus", normalized_name="ford_focus", year_from=2015, year_to=2020, power_kw=92, data_status="verified" ) db.add(model_def) await db.commit() # Generate tokens token1, _ = create_tokens(data={"sub": str(user1.id)}) token2, _ = create_tokens(data={"sub": str(user2.id)}) return token1, token2, org.id, branch.id, model_def.id async def run_tests(): print("--- SETUP ---") token1, token2, org_id, branch_id, model_id = await setup_test_data() print("Test data created successfully.") headers1 = {"Authorization": f"Bearer {token1}"} headers2 = {"Authorization": f"Bearer {token2}"} async with httpx.AsyncClient(base_url="http://127.0.0.1:8000") as client: print("\n--- TEST 1: CATALOG MATCH & GARAGE TEST ---") payload1 = { "vin": "TESTVIN1234567890", "license_plate": "TEST-123", "brand": "Ford", "model": "Focus", "year_of_manufacture": 2018, "organization_id": org_id, "vehicle_class": "car", "fuel_type": "petrol" } resp1 = await client.post("/api/v1/vehicles", json=payload1, headers=headers1) print(f"Status: {resp1.status_code}") try: data1 = resp1.json() print(f"Response: {data1}") if resp1.status_code == 201: assert data1["catalog_id"] == model_id, f"Matcher failed: expected {model_id}, got {data1.get('catalog_id')}" assert data1["branch_id"] == str(branch_id), f"Branch failed: expected {branch_id}, got {data1.get('branch_id')}" print("-> SUCCESS: Matcher assigned catalog and Main Branch assigned.") except Exception as e: print(f"-> FAILED: {e}") print("\n--- TEST 2: DRAFT / INCOMPLETE TEST ---") payload2 = { "license_plate": "DRAFT-456", "brand": "Ismeretlen", "organization_id": org_id } resp2 = await client.post("/api/v1/vehicles", json=payload2, headers=headers1) print(f"Status: {resp2.status_code}") try: data2 = resp2.json() print(f"Response: {data2}") if resp2.status_code == 201: assert data2["status"] == "draft", f"Status failed: expected 'draft', got {data2.get('status')}" assert data2["branch_id"] == str(branch_id), f"Branch failed: expected {branch_id}, got {data2.get('branch_id')}" print("-> SUCCESS: Draft created and Main Branch assigned.") except Exception as e: print(f"-> FAILED: {e}") print("\n--- TEST 3: OWNERSHIP TRANSFER TEST ---") payload3 = { "vin": "TESTVIN1234567890", "license_plate": "OTHER-123", "brand": "Ford", "model": "Focus", "organization_id": org_id } resp3 = await client.post("/api/v1/vehicles", json=payload3, headers=headers2) print(f"Status: {resp3.status_code}") try: data3 = resp3.json() print(f"Response: {data3}") if resp3.status_code == 202: print("-> SUCCESS: VIN collision detected (transfer_pending).") except Exception as e: print(f"-> FAILED: {e}") if __name__ == "__main__": asyncio.run(run_tests())