218 lines
7.5 KiB
Python
218 lines
7.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test Asset Logic - Validates AssetCreate schema, dynamic defaults, and draft/active logic.
|
|
This script must be run inside the sf_api container.
|
|
"""
|
|
import asyncio
|
|
import sys
|
|
import os
|
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
|
|
|
from app.db.session import AsyncSessionLocal
|
|
from app.schemas.asset import AssetCreate
|
|
from app.services.config_service import config
|
|
from datetime import datetime
|
|
|
|
async def test_asset_create_schema():
|
|
"""Test AssetCreate instantiation with various field combinations."""
|
|
print("=== Testing AssetCreate Schema ===")
|
|
|
|
# Test 1: Minimal required fields (license_plate only)
|
|
print("\n1. Minimal required fields (license_plate only):")
|
|
try:
|
|
asset = AssetCreate(license_plate="ABC-123")
|
|
print(f" Success: license_plate={asset.license_plate}")
|
|
print(f" vehicle_class={asset.vehicle_class}")
|
|
print(f" status={asset.status}")
|
|
print(f" brand={asset.brand}")
|
|
except Exception as e:
|
|
print(f" ❌ Error: {e}")
|
|
|
|
# Test 2: With vehicle_class provided
|
|
print("\n2. With vehicle_class provided:")
|
|
try:
|
|
asset = AssetCreate(license_plate="DEF-456", vehicle_class="SUV")
|
|
print(f" Success: vehicle_class={asset.vehicle_class}")
|
|
print(f" status={asset.status}")
|
|
except Exception as e:
|
|
print(f" ❌ Error: {e}")
|
|
|
|
# Test 3: All core fields (should be active)
|
|
print("\n3. All core fields (should be active):")
|
|
try:
|
|
asset = AssetCreate(
|
|
license_plate="GHI-789",
|
|
brand="Toyota",
|
|
model="Corolla",
|
|
vehicle_class="car",
|
|
fuel_type="petrol"
|
|
)
|
|
print(f" Success: status={asset.status}")
|
|
print(f" brand={asset.brand}, model={asset.model}")
|
|
print(f" vehicle_class={asset.vehicle_class}, fuel_type={asset.fuel_type}")
|
|
except Exception as e:
|
|
print(f" ❌ Error: {e}")
|
|
|
|
# Test 4: Missing one core field (should be draft)
|
|
print("\n4. Missing one core field (should be draft):")
|
|
try:
|
|
asset = AssetCreate(
|
|
license_plate="JKL-012",
|
|
brand="Toyota",
|
|
model="Corolla",
|
|
vehicle_class="car"
|
|
# fuel_type missing
|
|
)
|
|
print(f" Success: status={asset.status}")
|
|
print(f" fuel_type={asset.fuel_type}")
|
|
except Exception as e:
|
|
print(f" ❌ Error: {e}")
|
|
|
|
# Test 5: With catalog_id
|
|
print("\n5. With catalog_id:")
|
|
try:
|
|
asset = AssetCreate(
|
|
license_plate="MNO-345",
|
|
catalog_id=123
|
|
)
|
|
print(f" Success: catalog_id={asset.catalog_id}")
|
|
print(f" status={asset.status}")
|
|
except Exception as e:
|
|
print(f" ❌ Error: {e}")
|
|
|
|
print("\n=== Schema tests completed ===\n")
|
|
|
|
async def test_dynamic_default_vehicle_class():
|
|
"""Test that vehicle_class default is fetched from config_service."""
|
|
print("=== Testing Dynamic Default Vehicle Class ===")
|
|
|
|
async with AsyncSessionLocal() as db:
|
|
# First, check if DEFAULT_VEHICLE_CLASS parameter exists
|
|
default_class = await config.get_setting(db, "DEFAULT_VEHICLE_CLASS", default="car")
|
|
print(f"1. DEFAULT_VEHICLE_CLASS from config: '{default_class}'")
|
|
|
|
# Test 2: Create AssetCreate without vehicle_class, should not be hardcoded
|
|
print("\n2. Creating AssetCreate without vehicle_class:")
|
|
asset = AssetCreate(license_plate="TEST-001")
|
|
print(f" vehicle_class from schema: {asset.vehicle_class}")
|
|
print(f" Note: The schema doesn't set a default, so it's None.")
|
|
print(f" The service layer should use config default when needed.")
|
|
|
|
# Test 3: Verify config.get_setting works with different scopes
|
|
org_default = await config.get_setting(db, "DEFAULT_VEHICLE_CLASS", default="car", org_id=1)
|
|
print(f"\n3. DEFAULT_VEHICLE_CLASS with org_id=1: '{org_default}'")
|
|
|
|
# Test 4: Insert a test parameter and retrieve it
|
|
print("\n4. Testing parameter insertion and retrieval...")
|
|
from app.models.system.system import SystemParameter, ParameterScope
|
|
from sqlalchemy import select
|
|
|
|
# Check if parameter exists
|
|
stmt = select(SystemParameter).where(
|
|
SystemParameter.key == "DEFAULT_VEHICLE_CLASS",
|
|
SystemParameter.scope_level == ParameterScope.GLOBAL,
|
|
SystemParameter.is_active == True
|
|
)
|
|
result = await db.execute(stmt)
|
|
param = result.scalar_one_or_none()
|
|
|
|
if param:
|
|
print(f" Parameter exists: {param.value}")
|
|
else:
|
|
print(f" Parameter does not exist, using default 'car'")
|
|
|
|
print("\n=== Dynamic default tests completed ===\n")
|
|
|
|
async def test_draft_vs_active_logic():
|
|
"""Test the draft vs active status determination logic."""
|
|
print("=== Testing Draft vs Active Logic ===")
|
|
|
|
test_cases = [
|
|
{
|
|
"name": "All core fields",
|
|
"fields": {
|
|
"license_plate": "CORE-001",
|
|
"brand": "Ford",
|
|
"model": "Focus",
|
|
"vehicle_class": "car",
|
|
"fuel_type": "diesel"
|
|
},
|
|
"expected_status": "active"
|
|
},
|
|
{
|
|
"name": "Missing brand",
|
|
"fields": {
|
|
"license_plate": "CORE-002",
|
|
"model": "Focus",
|
|
"vehicle_class": "car",
|
|
"fuel_type": "diesel"
|
|
},
|
|
"expected_status": "draft"
|
|
},
|
|
{
|
|
"name": "Empty string brand",
|
|
"fields": {
|
|
"license_plate": "CORE-003",
|
|
"brand": "",
|
|
"model": "Focus",
|
|
"vehicle_class": "car",
|
|
"fuel_type": "diesel"
|
|
},
|
|
"expected_status": "draft"
|
|
},
|
|
{
|
|
"name": "Only license_plate",
|
|
"fields": {
|
|
"license_plate": "CORE-004"
|
|
},
|
|
"expected_status": "draft"
|
|
},
|
|
{
|
|
"name": "With catalog_id but missing core fields",
|
|
"fields": {
|
|
"license_plate": "CORE-005",
|
|
"catalog_id": 999
|
|
},
|
|
"expected_status": "draft"
|
|
},
|
|
]
|
|
|
|
for tc in test_cases:
|
|
print(f"\nTest: {tc['name']}")
|
|
try:
|
|
asset = AssetCreate(**tc['fields'])
|
|
status = asset.status
|
|
print(f" Fields: {list(tc['fields'].keys())}")
|
|
print(f" Expected status: {tc['expected_status']}")
|
|
print(f" Actual status: {status}")
|
|
if status == tc['expected_status']:
|
|
print(" ✅ PASS")
|
|
else:
|
|
print(" ❌ FAIL")
|
|
except Exception as e:
|
|
print(f" ❌ Error: {e}")
|
|
|
|
print("\n=== Draft/Active tests completed ===\n")
|
|
|
|
async def main():
|
|
"""Run all tests."""
|
|
print("🚀 Starting Asset Logic Tests")
|
|
print("=" * 50)
|
|
|
|
try:
|
|
await test_asset_create_schema()
|
|
await test_dynamic_default_vehicle_class()
|
|
await test_draft_vs_active_logic()
|
|
|
|
print("=" * 50)
|
|
print("✅ All tests completed successfully!")
|
|
return 0
|
|
except Exception as e:
|
|
print(f"❌ Critical error during tests: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return 1
|
|
|
|
if __name__ == "__main__":
|
|
exit_code = asyncio.run(main())
|
|
sys.exit(exit_code) |