teszt állományok áthelyezése és szelektálása
This commit is contained in:
16
tests/archive/check_asset_888.py.old
Normal file
16
tests/archive/check_asset_888.py.old
Normal file
@@ -0,0 +1,16 @@
|
||||
import asyncio
|
||||
from sqlalchemy import select
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.vehicle.asset import Asset
|
||||
|
||||
async def check():
|
||||
async with AsyncSessionLocal() as db:
|
||||
a = (await db.execute(select(Asset).where(Asset.license_plate == "TEST-888"))).scalar()
|
||||
if a:
|
||||
print("TEST-888 db branch_id:", a.branch_id)
|
||||
print("TEST-888 db catalog_id:", a.catalog_id)
|
||||
a2 = (await db.execute(select(Asset).where(Asset.license_plate == "DRAFT-888"))).scalar()
|
||||
if a2:
|
||||
print("DRAFT-888 db branch_id:", a2.branch_id)
|
||||
|
||||
asyncio.run(check())
|
||||
12
tests/archive/check_branch.py.old
Normal file
12
tests/archive/check_branch.py.old
Normal file
@@ -0,0 +1,12 @@
|
||||
import asyncio
|
||||
from sqlalchemy import select
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.marketplace.organization import Branch
|
||||
|
||||
async def check():
|
||||
async with AsyncSessionLocal() as db:
|
||||
o = (await db.execute(select(Branch).limit(5))).scalars().all()
|
||||
for i in o:
|
||||
print(i.id, i.organization_id, i.is_main)
|
||||
|
||||
asyncio.run(check())
|
||||
16
tests/archive/check_db.py.old
Normal file
16
tests/archive/check_db.py.old
Normal file
@@ -0,0 +1,16 @@
|
||||
import asyncio
|
||||
from sqlalchemy import select
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.identity import User
|
||||
from app.models.marketplace.organization import Organization
|
||||
|
||||
async def check():
|
||||
async with AsyncSessionLocal() as db:
|
||||
u = (await db.execute(select(User).limit(5))).scalars().all()
|
||||
o = (await db.execute(select(Organization).limit(5))).scalars().all()
|
||||
print(f"Users: {len(u)}")
|
||||
print(f"Orgs: {len(o)}")
|
||||
if u: print(u[0].id)
|
||||
if o: print(o[0].id)
|
||||
|
||||
asyncio.run(check())
|
||||
27
tests/archive/check_user_scope.py.old
Normal file
27
tests/archive/check_user_scope.py.old
Normal file
@@ -0,0 +1,27 @@
|
||||
import asyncio
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.identity import User
|
||||
from app.core.security import create_tokens
|
||||
from sqlalchemy import select
|
||||
|
||||
async def main():
|
||||
async with AsyncSessionLocal() as db:
|
||||
result = await db.execute(select(User).where(User.id == 28))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
print("User 28 not found")
|
||||
return
|
||||
|
||||
print(f"User found: {user.email}, Scope ID: {user.scope_id}, Scope Level: {user.scope_level}")
|
||||
|
||||
# Check organization membership
|
||||
from app.models.marketplace.organization import OrganizationMember
|
||||
org_result = await db.execute(
|
||||
select(OrganizationMember).where(OrganizationMember.user_id == 28)
|
||||
)
|
||||
memberships = org_result.scalars().all()
|
||||
for m in memberships:
|
||||
print(f"Organization membership: org_id={m.organization_id}, role={m.role}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
12
tests/archive/check_vmd.py.old
Normal file
12
tests/archive/check_vmd.py.old
Normal file
@@ -0,0 +1,12 @@
|
||||
import asyncio
|
||||
from sqlalchemy import select
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.vehicle.vehicle_definitions import VehicleModelDefinition
|
||||
|
||||
async def check():
|
||||
async with AsyncSessionLocal() as db:
|
||||
o = (await db.execute(select(VehicleModelDefinition).where(VehicleModelDefinition.make=="Ford", VehicleModelDefinition.marketing_name=="Focus"))).scalars().all()
|
||||
for i in o:
|
||||
print(i.id, i.make, i.marketing_name, i.year_from, i.year_to)
|
||||
|
||||
asyncio.run(check())
|
||||
92
tests/archive/complete_kyc_script.py.old
Normal file
92
tests/archive/complete_kyc_script.py.old
Normal file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Complete KYC for User 55 with test data
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
from datetime import datetime
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from app.services.auth_service import AuthService
|
||||
from app.core.config import settings
|
||||
from app.schemas.auth import UserKYCComplete
|
||||
|
||||
async def complete_kyc_for_user_55():
|
||||
# Create database connection
|
||||
engine = create_async_engine(settings.DATABASE_URL, echo=False)
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
async with async_session() as db:
|
||||
print("🔍 Completing KYC for User 55")
|
||||
|
||||
# Prepare KYC data
|
||||
kyc_data = UserKYCComplete(
|
||||
phone_number="+36301234567",
|
||||
address_zip="1234",
|
||||
address_city="Budapest",
|
||||
address_street_name="Teszt utca",
|
||||
address_street_type="utca",
|
||||
address_house_number="1",
|
||||
address_hrsz=None,
|
||||
mothers_last_name="Teszt",
|
||||
mothers_first_name="Anya",
|
||||
birth_place="Budapest",
|
||||
birth_date=datetime(1990, 1, 1).date(),
|
||||
identity_docs={
|
||||
"ID_CARD": {
|
||||
"number": "123456AB",
|
||||
"expiry_date": "2030-01-01"
|
||||
}
|
||||
},
|
||||
ice_contact={
|
||||
"name": "Teszt ICE Kapcsolat",
|
||||
"phone": "+36309876543",
|
||||
"relationship": "családtag"
|
||||
},
|
||||
preferred_currency="HUF"
|
||||
)
|
||||
|
||||
print(f"KYC data: {kyc_data.model_dump_json(indent=2)}")
|
||||
|
||||
# Call the complete_kyc method
|
||||
try:
|
||||
user = await AuthService.complete_kyc(db, 55, kyc_data)
|
||||
|
||||
if user:
|
||||
print("✅ KYC completion successful!")
|
||||
print(f"User 55 status after KYC:")
|
||||
print(f" - is_active: {user.is_active}")
|
||||
print(f" - person_id: {user.person_id}")
|
||||
print(f" - scope_id: {user.scope_id}")
|
||||
|
||||
# Check person details
|
||||
from sqlalchemy import select
|
||||
from app.models.identity import Person
|
||||
|
||||
result = await db.execute(select(Person).where(Person.id == user.person_id))
|
||||
person = result.scalar_one_or_none()
|
||||
|
||||
if person:
|
||||
print(f"Person {person.id} details:")
|
||||
print(f" - phone: {person.phone}")
|
||||
print(f" - address_id: {person.address_id}")
|
||||
print(f" - is_active: {person.is_active}")
|
||||
|
||||
return True
|
||||
else:
|
||||
print("❌ KYC completion failed - user not found")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ KYC completion error: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = asyncio.run(complete_kyc_for_user_55())
|
||||
sys.exit(0 if result else 1)
|
||||
181
tests/archive/create_business_org.py.old
Normal file
181
tests/archive/create_business_org.py.old
Normal file
@@ -0,0 +1,181 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Script to create a business organization for User 55 (Test-Robot Kft.)
|
||||
"""
|
||||
import sys
|
||||
import asyncio
|
||||
from datetime import datetime, timezone
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
sys.path.append('/app/backend')
|
||||
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.marketplace import Organization, OrganizationMember, Branch, OrgType
|
||||
from app.models.identity import User
|
||||
from app.core.security import generate_secure_slug
|
||||
from app.services.geo_service import GeoService
|
||||
|
||||
async def create_business_organization():
|
||||
"""Create a business organization for User 55"""
|
||||
async with AsyncSessionLocal() as db:
|
||||
try:
|
||||
# Get User 55
|
||||
user_result = await db.execute(select(User).where(User.id == 55))
|
||||
user = user_result.scalar_one_or_none()
|
||||
|
||||
if not user:
|
||||
print("ERROR: User 55 not found")
|
||||
return
|
||||
|
||||
print(f"Found user: {user.email}")
|
||||
|
||||
# Check if business organization already exists for this user
|
||||
org_check = await db.execute(
|
||||
select(Organization).join(OrganizationMember).where(
|
||||
OrganizationMember.user_id == 55,
|
||||
Organization.org_type == OrgType.business
|
||||
)
|
||||
)
|
||||
existing_business = org_check.scalar_one_or_none()
|
||||
|
||||
if existing_business:
|
||||
print(f"Business organization already exists: {existing_business.full_name} (ID: {existing_business.id})")
|
||||
return existing_business.id
|
||||
|
||||
# Create address for the business (using user's address or creating new)
|
||||
# For simplicity, using the same address as user's person
|
||||
from app.models.identity import Person
|
||||
person_result = await db.execute(select(Person).where(Person.id == user.person_id))
|
||||
person = person_result.scalar_one_or_none()
|
||||
|
||||
address_id = None
|
||||
if person and person.address_id:
|
||||
address_id = person.address_id
|
||||
print(f"Using existing address ID: {address_id}")
|
||||
else:
|
||||
# Create a simple address for the business
|
||||
address_data = {
|
||||
"zip_code": "1132",
|
||||
"city": "Budapest",
|
||||
"street_name": "Váci",
|
||||
"street_type": "út",
|
||||
"house_number": "47",
|
||||
"parcel_id": None
|
||||
}
|
||||
address_id = await GeoService.get_or_create_full_address(db, **address_data)
|
||||
print(f"Created new address ID: {address_id}")
|
||||
|
||||
# Create the business organization
|
||||
now = datetime.now(timezone.utc)
|
||||
business_org = Organization(
|
||||
full_name="Test-Robot Kft.",
|
||||
name="Test-Robot Kft.",
|
||||
display_name="Test-Robot",
|
||||
folder_slug=generate_secure_slug(12),
|
||||
org_type=OrgType.business,
|
||||
owner_id=user.id,
|
||||
legal_owner_id=person.id if person else None,
|
||||
tax_number="12345678-1-12",
|
||||
reg_number="01-09-123456",
|
||||
is_active=True,
|
||||
status="verified",
|
||||
country_code="HU",
|
||||
language="hu",
|
||||
default_currency="HUF",
|
||||
address_id=address_id,
|
||||
address_zip="1132",
|
||||
address_city="Budapest",
|
||||
address_street_name="Váci",
|
||||
address_street_type="út",
|
||||
address_house_number="47",
|
||||
first_registered_at=now,
|
||||
current_lifecycle_started_at=now,
|
||||
subscription_plan="FREE",
|
||||
base_asset_limit=10,
|
||||
purchased_extra_slots=0,
|
||||
notification_settings={},
|
||||
external_integration_config={},
|
||||
is_ownership_transferable=True,
|
||||
created_at=now
|
||||
)
|
||||
|
||||
db.add(business_org)
|
||||
await db.flush()
|
||||
print(f"Created business organization: {business_org.full_name} (ID: {business_org.id})")
|
||||
|
||||
# Add user as OWNER of the organization
|
||||
org_member = OrganizationMember(
|
||||
organization_id=business_org.id,
|
||||
user_id=user.id,
|
||||
role="OWNER",
|
||||
is_active=True,
|
||||
joined_at=now
|
||||
)
|
||||
db.add(org_member)
|
||||
|
||||
# Create main branch
|
||||
main_branch = Branch(
|
||||
organization_id=business_org.id,
|
||||
address_id=address_id,
|
||||
name="Központi Telephely",
|
||||
is_main=True,
|
||||
phone=person.phone if person else "+36301234567",
|
||||
email=user.email,
|
||||
operating_hours={},
|
||||
services_offered=[],
|
||||
created_at=now
|
||||
)
|
||||
db.add(main_branch)
|
||||
|
||||
await db.commit()
|
||||
print(f"Created main branch: {main_branch.name}")
|
||||
print(f"Added user as OWNER to organization")
|
||||
|
||||
return business_org.id
|
||||
|
||||
except Exception as e:
|
||||
await db.rollback()
|
||||
print(f"ERROR: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return None
|
||||
|
||||
async def verify_organizations():
|
||||
"""Verify that User 55 has access to both organizations"""
|
||||
async with AsyncSessionLocal() as db:
|
||||
# Get all organizations for User 55
|
||||
result = await db.execute(
|
||||
select(Organization, OrganizationMember.role)
|
||||
.join(OrganizationMember)
|
||||
.where(OrganizationMember.user_id == 55)
|
||||
.order_by(Organization.org_type)
|
||||
)
|
||||
orgs = result.all()
|
||||
|
||||
print("\n=== VERIFICATION ===")
|
||||
print(f"User 55 has access to {len(orgs)} organizations:")
|
||||
|
||||
for org, role in orgs:
|
||||
print(f" - {org.full_name} (ID: {org.id}, Type: {org.org_type}, Role: {role})")
|
||||
|
||||
# Check branches
|
||||
if orgs:
|
||||
for org, _ in orgs:
|
||||
branch_result = await db.execute(
|
||||
select(Branch).where(Branch.organization_id == org.id)
|
||||
)
|
||||
branches = branch_result.scalars().all()
|
||||
print(f" Branches for {org.name}: {len(branches)}")
|
||||
for branch in branches:
|
||||
print(f" - {branch.name} (Main: {branch.is_main})")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== CREATING BUSINESS ORGANIZATION FOR USER 55 ===")
|
||||
org_id = asyncio.run(create_business_organization())
|
||||
|
||||
if org_id:
|
||||
print(f"\nBusiness organization created successfully with ID: {org_id}")
|
||||
asyncio.run(verify_organizations())
|
||||
else:
|
||||
print("\nFailed to create business organization")
|
||||
143
tests/archive/create_business_via_api.py.old
Normal file
143
tests/archive/create_business_via_api.py.old
Normal file
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Create a business organization for User 55 using the official API endpoint.
|
||||
"""
|
||||
import sys
|
||||
import asyncio
|
||||
import httpx
|
||||
import json
|
||||
|
||||
sys.path.append('/app/backend')
|
||||
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from sqlalchemy import select
|
||||
from app.models.identity import User
|
||||
from app.core.security import create_tokens
|
||||
|
||||
async def get_auth_token():
|
||||
"""Get authentication token for User 55"""
|
||||
async with AsyncSessionLocal() as db:
|
||||
result = await db.execute(select(User).where(User.id == 55))
|
||||
user = result.scalar_one_or_none()
|
||||
if user:
|
||||
access_token, _ = create_tokens(data={'sub': str(user.id)})
|
||||
return access_token
|
||||
else:
|
||||
raise Exception("User 55 not found")
|
||||
|
||||
async def create_business_organization():
|
||||
"""Create business organization via API"""
|
||||
# Get auth token
|
||||
token = await get_auth_token()
|
||||
print(f"Auth token obtained for User 55")
|
||||
|
||||
# Prepare API request
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
payload = {
|
||||
"full_name": "Test-Robot Kft.",
|
||||
"name": "Test-Robot Kft.",
|
||||
"display_name": "Test-Robot",
|
||||
"tax_number": "12345678-1-12",
|
||||
"reg_number": "01-09-123456",
|
||||
"country_code": "HU",
|
||||
"language": "hu",
|
||||
"default_currency": "HUF",
|
||||
# Atomic address fields
|
||||
"address_zip": "1132",
|
||||
"address_city": "Budapest",
|
||||
"address_street_name": "Váci",
|
||||
"address_street_type": "út",
|
||||
"address_house_number": "47",
|
||||
"address_stairwell": "A",
|
||||
"address_floor": "1",
|
||||
"address_door": "1",
|
||||
"address_hrsz": None,
|
||||
"contacts": [
|
||||
{
|
||||
"full_name": "Test User",
|
||||
"email": "test_fallback@profibot.hu",
|
||||
"phone": "+36301234567",
|
||||
"contact_type": "primary"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Make API call
|
||||
async with httpx.AsyncClient(base_url="http://sf_api:8000", timeout=30.0) as client:
|
||||
try:
|
||||
print("Sending POST request to /api/v1/organizations/onboard...")
|
||||
response = await client.post(
|
||||
"/api/v1/organizations/onboard",
|
||||
json=payload,
|
||||
headers=headers
|
||||
)
|
||||
|
||||
print(f"Response status: {response.status_code}")
|
||||
print(f"Response body: {response.text}")
|
||||
|
||||
if response.status_code in (200, 201):
|
||||
result = response.json()
|
||||
print(f"\n✅ Business organization created successfully!")
|
||||
print(f"Organization ID: {result.get('organization_id')}")
|
||||
print(f"Status: {result.get('status')}")
|
||||
return result.get('organization_id')
|
||||
else:
|
||||
print(f"\n❌ Failed to create organization")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error making API request: {e}")
|
||||
return None
|
||||
|
||||
async def verify_organizations():
|
||||
"""Verify User 55's organizations"""
|
||||
async with AsyncSessionLocal() as db:
|
||||
from sqlalchemy import text
|
||||
|
||||
print("\n=== VERIFYING ORGANIZATIONS FOR USER 55 ===")
|
||||
|
||||
# Get all organizations for User 55
|
||||
result = await db.execute(text('''
|
||||
SELECT o.id, o.full_name, o.org_type, o.tax_number, o.status, om.role
|
||||
FROM fleet.organizations o
|
||||
JOIN fleet.organization_members om ON o.id = om.organization_id
|
||||
WHERE om.user_id = 55
|
||||
ORDER BY o.org_type
|
||||
'''))
|
||||
orgs = result.fetchall()
|
||||
|
||||
print(f"User 55 has access to {len(orgs)} organizations:")
|
||||
|
||||
for org in orgs:
|
||||
org_dict = dict(org._mapping)
|
||||
print(f" - {org_dict['full_name']} (ID: {org_dict['id']}, Type: {org_dict['org_type']}, Tax: {org_dict['tax_number']}, Role: {org_dict['role']})")
|
||||
|
||||
# Check branches
|
||||
from app.models.marketplace import Branch
|
||||
from sqlalchemy import select
|
||||
|
||||
for org in orgs:
|
||||
org_id = dict(org._mapping)['id']
|
||||
branch_result = await db.execute(
|
||||
select(Branch).where(Branch.organization_id == org_id)
|
||||
)
|
||||
branches = branch_result.scalars().all()
|
||||
print(f" Branches for org {org_id}: {len(branches)}")
|
||||
for branch in branches:
|
||||
print(f" - {branch.name} (Main: {branch.is_main})")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== CREATING BUSINESS ORGANIZATION VIA API ===")
|
||||
|
||||
# Run the async functions
|
||||
org_id = asyncio.run(create_business_organization())
|
||||
|
||||
if org_id:
|
||||
print(f"\n✅ Business organization created with ID: {org_id}")
|
||||
asyncio.run(verify_organizations())
|
||||
else:
|
||||
print("\n❌ Failed to create business organization")
|
||||
98
tests/archive/create_vehicle_for_org.py.old
Normal file
98
tests/archive/create_vehicle_for_org.py.old
Normal file
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Script to create a vehicle for Organization 34 and Branch 18fcd55f...
|
||||
"""
|
||||
import asyncio
|
||||
import aiohttp
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, '/app')
|
||||
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.identity import User
|
||||
from app.core.security import create_tokens
|
||||
from sqlalchemy import select
|
||||
|
||||
async def get_token_for_user(user_id: int):
|
||||
"""Generate JWT token for given user."""
|
||||
async with AsyncSessionLocal() as db:
|
||||
result = await db.execute(select(User).where(User.id == user_id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
raise ValueError(f"User {user_id} not found")
|
||||
|
||||
token_payload = {
|
||||
"sub": str(user.id),
|
||||
"role": user.role.value if hasattr(user.role, 'value') else user.role,
|
||||
"rank": 10,
|
||||
"scope_level": user.scope_level.value if hasattr(user.scope_level, 'value') else (user.scope_level or "individual"),
|
||||
"scope_id": str(user.scope_id) if user.scope_id else str(user.id)
|
||||
}
|
||||
access_token, refresh_token = create_tokens(data=token_payload)
|
||||
return access_token
|
||||
|
||||
async def create_vehicle(token: str):
|
||||
"""POST /api/v1/assets/vehicles with test data."""
|
||||
url = "http://sf_api:8000/api/v1/assets/vehicles"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
# Branch ID: 18fcd55f... (need full UUID). Let's find it from database.
|
||||
async with AsyncSessionLocal() as db:
|
||||
from app.models.marketplace.organization import Branch
|
||||
result = await db.execute(select(Branch).where(Branch.organization_id == 34))
|
||||
branches = result.scalars().all()
|
||||
for b in branches:
|
||||
print(f"Branch: {b.id}, name: {b.name}")
|
||||
# Use the first branch with ID starting with 18fcd55f
|
||||
if str(b.id).startswith("18fcd55f"):
|
||||
branch_id = b.id
|
||||
break
|
||||
else:
|
||||
# fallback to first branch
|
||||
if branches:
|
||||
branch_id = branches[0].id
|
||||
else:
|
||||
raise ValueError("No branch found for organization 34")
|
||||
|
||||
payload = {
|
||||
"license_plate": "ABC-123",
|
||||
"vin": "1HGCM82633A123456",
|
||||
"brand": "Toyota",
|
||||
"model": "Corolla",
|
||||
"vehicle_class": "Passenger Car",
|
||||
"fuel_type": "Petrol",
|
||||
"organization_id": 34,
|
||||
# branch_id is not in schema? Actually branch_id is not in AssetCreate.
|
||||
# The branch assignment likely happens via organization_id and garage logic.
|
||||
# We'll rely on the service to assign to the correct branch.
|
||||
}
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, headers=headers, json=payload) as resp:
|
||||
print(f"Status: {resp.status}")
|
||||
response_text = await resp.text()
|
||||
print(f"Response: {response_text}")
|
||||
if resp.status == 201:
|
||||
data = await resp.json()
|
||||
print(f"Vehicle created successfully: ID={data.get('id')}")
|
||||
return data
|
||||
else:
|
||||
raise Exception(f"Failed to create vehicle: {resp.status} {response_text}")
|
||||
|
||||
async def main():
|
||||
try:
|
||||
token = await get_token_for_user(28)
|
||||
print(f"Token obtained: {token[:30]}...")
|
||||
vehicle = await create_vehicle(token)
|
||||
print("Vehicle creation successful.")
|
||||
print(f"Vehicle ID: {vehicle['id']}")
|
||||
print(f"Status: {vehicle.get('status')}")
|
||||
print(f"Data Enrichment Status: {vehicle.get('data_status')}")
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
94
tests/archive/create_vehicle_via_api.py.old
Normal file
94
tests/archive/create_vehicle_via_api.py.old
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Create a vehicle via external API call (from host).
|
||||
"""
|
||||
import requests
|
||||
import json
|
||||
import sys
|
||||
|
||||
BASE_URL = "http://192.168.100.10:8000"
|
||||
|
||||
def get_token():
|
||||
"""Login with user 28 credentials."""
|
||||
# We need to know the password for user 28. Let's try to get token via internal script.
|
||||
# Instead, we can use a known token from previous runs.
|
||||
# Let's try to fetch token via login endpoint with email/password.
|
||||
# Need to find user 28 email. Check database via docker exec.
|
||||
# For simplicity, we can use the token generation script inside container.
|
||||
# We'll run a docker command to get token.
|
||||
import subprocess
|
||||
result = subprocess.run(
|
||||
["docker", "compose", "exec", "-T", "sf_api", "python3", "-c", """
|
||||
import asyncio
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.identity import User
|
||||
from app.core.security import create_tokens
|
||||
from sqlalchemy import select
|
||||
import sys
|
||||
|
||||
async def main():
|
||||
async with AsyncSessionLocal() as db:
|
||||
result = await db.execute(select(User).where(User.id == 28))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
print("NOTFOUND")
|
||||
return
|
||||
token_payload = {
|
||||
"sub": str(user.id),
|
||||
"role": user.role.value if hasattr(user.role, 'value') else user.role,
|
||||
"rank": 10,
|
||||
"scope_level": user.scope_level.value if hasattr(user.scope_level, 'value') else (user.scope_level or "individual"),
|
||||
"scope_id": str(user.scope_id) if user.scope_id else str(user.id)
|
||||
}
|
||||
access_token, refresh_token = create_tokens(data=token_payload)
|
||||
print(access_token)
|
||||
|
||||
asyncio.run(main())
|
||||
"""],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
if result.returncode == 0:
|
||||
token = result.stdout.strip()
|
||||
if token and token != "NOTFOUND":
|
||||
return token
|
||||
# fallback: maybe there is a test token in env
|
||||
return None
|
||||
|
||||
def main():
|
||||
token = get_token()
|
||||
if not token:
|
||||
print("Failed to obtain token")
|
||||
sys.exit(1)
|
||||
print(f"Token: {token[:30]}...")
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
payload = {
|
||||
"license_plate": "ABC-123",
|
||||
"vin": "1HGCM82633A123456",
|
||||
"brand": "Toyota",
|
||||
"model": "Corolla",
|
||||
"vehicle_class": "Passenger Car",
|
||||
"fuel_type": "Petrol",
|
||||
"organization_id": 34
|
||||
}
|
||||
|
||||
resp = requests.post(f"{BASE_URL}/api/v1/assets/vehicles", headers=headers, json=payload)
|
||||
print(f"Status: {resp.status_code}")
|
||||
print(f"Response: {resp.text}")
|
||||
if resp.status_code == 201:
|
||||
data = resp.json()
|
||||
print(f"Vehicle created successfully: ID={data.get('id')}")
|
||||
print(f"Status: {data.get('status')}")
|
||||
print(f"Data Enrichment Status: {data.get('data_status')}")
|
||||
return data
|
||||
else:
|
||||
print("Failed to create vehicle")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
67
tests/archive/full_discovery_bot.py.old
Executable file
67
tests/archive/full_discovery_bot.py.old
Executable file
@@ -0,0 +1,67 @@
|
||||
import asyncio
|
||||
from sqlalchemy import text
|
||||
from app.db.session import engine
|
||||
|
||||
# 200+ Márka és Típus adatok
|
||||
DATA = {
|
||||
"CAR": {
|
||||
"Toyota": ["Corolla", "Yaris", "RAV4", "Hilux", "C-HR", "Land Cruiser", "Camry"],
|
||||
"Volkswagen": ["Golf", "Passat", "Polo", "Tiguan", "T-Roc", "Arteon", "Caddy"],
|
||||
"BMW": ["3 Series", "5 Series", "X5", "X3", "1 Series", "7 Series", "X1"],
|
||||
"Mercedes-Benz": ["C-Class", "E-Class", "S-Class", "GLC", "GLE", "A-Class", "CLA"],
|
||||
"Audi": ["A3", "A4", "A6", "Q3", "Q5", "Q7", "A5", "TT"],
|
||||
"Ford": ["Focus", "Fiesta", "Kuga", "Puma", "Transit", "Ranger", "Mondeo", "Mustang"],
|
||||
"Opel": ["Astra", "Corsa", "Insignia", "Mokka", "Grandland", "Crossland", "Vivaro"],
|
||||
"Suzuki": ["Swift", "Vitara", "S-Cross", "Ignis", "Jimny", "Baleno"],
|
||||
"Skoda": ["Octavia", "Fabia", "Superb", "Kodiaq", "Karoq", "Kamiq", "Scala"],
|
||||
"Hyundai": ["i30", "Tucson", "i20", "Kona", "Santa Fe", "Ioniq 5", "Bayon"],
|
||||
"Kia": ["Ceed", "Sportage", "Rio", "Niro", "Sorento", "Picanto", "Stonic"],
|
||||
"Renault": ["Clio", "Megane", "Captur", "Kadjar", "Master", "Trafic", "Zoe", "Arkana"],
|
||||
"Peugeot": ["208", "308", "2008", "3008", "5008", "508", "Rifter"],
|
||||
"Volvo": ["XC60", "XC40", "XC90", "V60", "S60", "V90", "S90"],
|
||||
"Mazda": ["CX-5", "Mazda3", "Mazda6", "CX-30", "MX-5", "CX-3"],
|
||||
"Fiat": ["500", "Panda", "Tipo", "Ducato", "Doblo", "500X"],
|
||||
"Dacia": ["Duster", "Sandero", "Logan", "Jogger", "Spring"],
|
||||
"Nissan": ["Qashqai", "Juke", "X-Trail", "Leaf", "Micra", "Navara"],
|
||||
"Tesla": ["Model 3", "Model Y", "Model S", "Model X"],
|
||||
"Lexus": ["RX", "NX", "UX", "ES", "IS", "LS"]
|
||||
},
|
||||
"MOTORCYCLE": {
|
||||
"Honda": ["CB500", "CBR600", "Africa Twin", "NC750X", "Goldwing", "PCX", "SH125", "Forza 350"],
|
||||
"Yamaha": ["MT-07", "MT-09", "R1", "R6", "Tracer 9", "Ténéré 700", "XMAX", "TMAX"],
|
||||
"Kawasaki": ["Ninja 400", "Ninja 650", "Z900", "Z650", "Versys 650", "Vulcan S", "Z1000"],
|
||||
"Suzuki": ["V-Strom 650", "GSX-R1000", "Hayabusa", "SV650", "Burgman", "GSX-S1000"],
|
||||
"BMW Motorrad": ["R1250GS", "S1000RR", "F850GS", "R nineT", "G310GS", "K1600GT"],
|
||||
"KTM": ["Duke 390", "Duke 790", "1290 Super Adventure", "300 EXC", "890 Adventure"],
|
||||
"Ducati": ["Monster", "Multistrada", "Panigale V4", "Scrambler", "Diavel", "Streetfighter"],
|
||||
"Harley-Davidson": ["Sportster", "Fat Boy", "Iron 883", "Pan America", "Road Glide"]
|
||||
}
|
||||
}
|
||||
|
||||
async def run_discovery():
|
||||
async with engine.begin() as conn:
|
||||
print("🚀 Jármű adatbázis mély-feltöltése indul...")
|
||||
|
||||
for cat_name, brands in DATA.items():
|
||||
res = await conn.execute(text("SELECT id FROM data.vehicle_categories WHERE name = :n"), {"n": cat_name})
|
||||
cat_id = res.scalar()
|
||||
|
||||
for brand_name, models in brands.items():
|
||||
# Márka beszúrása
|
||||
await conn.execute(text(
|
||||
"INSERT INTO data.vehicle_brands (category_id, name) VALUES (:c, :n) ON CONFLICT (category_id, name) DO NOTHING"
|
||||
), {"c": cat_id, "n": brand_name})
|
||||
|
||||
# Márka ID lekérése
|
||||
res_b = await conn.execute(text("SELECT id FROM data.vehicle_brands WHERE name = :n AND category_id = :c"), {"n": brand_name, "c": cat_id})
|
||||
brand_id = res_b.scalar()
|
||||
|
||||
for m_name in models:
|
||||
await conn.execute(text(
|
||||
"INSERT INTO data.vehicle_models (brand_id, name) VALUES (:b, :n) ON CONFLICT (brand_id, name) DO NOTHING"
|
||||
), {"b": brand_id, "n": m_name})
|
||||
|
||||
print("✅ Discovery Bot sikeresen betöltötte az adatokat!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(run_discovery())
|
||||
28
tests/archive/get_token_for_user_29.py.old
Normal file
28
tests/archive/get_token_for_user_29.py.old
Normal file
@@ -0,0 +1,28 @@
|
||||
import asyncio
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.identity import User
|
||||
from app.core.security import create_tokens
|
||||
from sqlalchemy import select
|
||||
|
||||
async def main():
|
||||
async with AsyncSessionLocal() as db:
|
||||
result = await db.execute(select(User).where(User.id == 29))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
print("User 29 not found")
|
||||
return
|
||||
|
||||
print(f"User found: {user.email}, Scope ID: {user.scope_id}")
|
||||
|
||||
token_payload = {
|
||||
"sub": str(user.id),
|
||||
"role": user.role.value if hasattr(user.role, 'value') else user.role,
|
||||
"rank": 10,
|
||||
"scope_level": user.scope_level.value if hasattr(user.scope_level, 'value') else (user.scope_level or "individual"),
|
||||
"scope_id": str(user.scope_id) if user.scope_id else str(user.id)
|
||||
}
|
||||
access_token, refresh_token = create_tokens(data=token_payload)
|
||||
print(f"TOKEN={access_token}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
51
tests/archive/manual_verification.py.old
Normal file
51
tests/archive/manual_verification.py.old
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Manual verification script for User 55 with token 2f39c71d-80f2-44c1-bac4-dab4f384aae8
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from app.services.auth_service import AuthService
|
||||
from app.core.config import settings
|
||||
|
||||
async def verify_user_55():
|
||||
# Create database connection
|
||||
engine = create_async_engine(settings.DATABASE_URL, echo=False)
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
async with async_session() as db:
|
||||
print("🔍 Manual verification for User 55")
|
||||
print(f"Token: 2f39c71d-80f2-44c1-bac4-dab4f384aae8")
|
||||
|
||||
# Call the verify_email method
|
||||
success = await AuthService.verify_email(db, "2f39c71d-80f2-44c1-bac4-dab4f384aae8")
|
||||
|
||||
if success:
|
||||
print("✅ Email verification successful!")
|
||||
|
||||
# Check if user is now active
|
||||
from sqlalchemy import select
|
||||
from app.models.identity import User
|
||||
|
||||
result = await db.execute(select(User).where(User.id == 55))
|
||||
user = result.scalar_one_or_none()
|
||||
|
||||
if user:
|
||||
print(f"User 55 status:")
|
||||
print(f" - is_active: {user.is_active}")
|
||||
print(f" - email: {user.email}")
|
||||
print(f" - person_id: {user.person_id}")
|
||||
else:
|
||||
print("❌ User 55 not found!")
|
||||
else:
|
||||
print("❌ Email verification failed - invalid or expired token")
|
||||
|
||||
return success
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = asyncio.run(verify_user_55())
|
||||
sys.exit(0 if result else 1)
|
||||
70
tests/archive/patch_auth_login.py.old
Normal file
70
tests/archive/patch_auth_login.py.old
Normal file
@@ -0,0 +1,70 @@
|
||||
import re
|
||||
|
||||
with open("/opt/docker/dev/service_finder/backend/app/api/v1/endpoints/auth.py", "r") as f:
|
||||
content = f.read()
|
||||
|
||||
# Add Response to imports if not there
|
||||
if "from fastapi import APIRouter, Depends, HTTPException, status, Request, Form, Response" not in content:
|
||||
content = content.replace(
|
||||
"from fastapi import APIRouter, Depends, HTTPException, status, Request, Form",
|
||||
"from fastapi import APIRouter, Depends, HTTPException, status, Request, Form, Response"
|
||||
)
|
||||
|
||||
new_login = """
|
||||
@router.post("/login", response_model=Token)
|
||||
async def login(
|
||||
response: Response,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
form_data: OAuth2PasswordRequestForm = Depends(),
|
||||
remember_me: bool = Form(False)
|
||||
):
|
||||
\"\"\"
|
||||
Bejelentkezés remember_me opcióval.
|
||||
|
||||
A remember_me paramétert explicit Form mezőként kell elküldeni, mivel az
|
||||
OAuth2PasswordRequestForm nem támogatja alapból.
|
||||
\"\"\"
|
||||
user = await AuthService.authenticate(db, form_data.username, form_data.password)
|
||||
if not user:
|
||||
raise HTTPException(status_code=401, detail="Hibás adatok.")
|
||||
|
||||
ranks = await settings.get_db_setting(db, "rbac_rank_matrix", default=DEFAULT_RANK_MAP)
|
||||
role_name = user.role.value if hasattr(user.role, 'value') else str(user.role)
|
||||
role_key = role_name.upper() # A DEFAULT_RANK_MAP nagybetűs kulcsokat vár
|
||||
|
||||
token_data = {
|
||||
"sub": str(user.id),
|
||||
"role": role_name,
|
||||
"rank": ranks.get(role_key, 10),
|
||||
"scope_level": user.scope_level or "individual",
|
||||
"scope_id": str(user.scope_id) if user.scope_id else str(user.id)
|
||||
}
|
||||
|
||||
access, refresh = create_tokens(data=token_data, remember_me=remember_me)
|
||||
|
||||
# Kinyerjük a beállításokból, hogy meddig él a refresh token (itt is, vagy a create_tokens is ezt csinálja)
|
||||
# A SSoT szerint auth_remember_me_days = 30
|
||||
if remember_me:
|
||||
max_age_days = await config.get_setting(db, "auth_remember_me_days", default=30)
|
||||
else:
|
||||
max_age_days = await config.get_setting(db, "auth_refresh_default_days", default=1)
|
||||
|
||||
max_age_sec = int(max_age_days) * 24 * 60 * 60
|
||||
|
||||
response.set_cookie(
|
||||
key="refresh_token",
|
||||
value=refresh,
|
||||
httponly=True,
|
||||
secure=True, # Use Secure
|
||||
samesite="lax",
|
||||
max_age=max_age_sec
|
||||
)
|
||||
|
||||
return {"access_token": access, "refresh_token": refresh, "token_type": "bearer", "is_active": user.is_active}
|
||||
"""
|
||||
|
||||
pattern = r'@router\.post\("/login", response_model=Token\)\nasync def login\(.*?\):\n(?:.*?(?=@router\.post|class VerifyEmailRequest))'
|
||||
content = re.sub(pattern, new_login.strip() + "\n\n", content, flags=re.DOTALL)
|
||||
|
||||
with open("/opt/docker/dev/service_finder/backend/app/api/v1/endpoints/auth.py", "w") as f:
|
||||
f.write(content)
|
||||
70
tests/archive/patch_auth_service.py.old
Normal file
70
tests/archive/patch_auth_service.py.old
Normal file
@@ -0,0 +1,70 @@
|
||||
import re
|
||||
|
||||
with open('backend/app/services/auth_service.py', 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
shadow_logic = """
|
||||
p = user.person
|
||||
|
||||
# --- SHADOW IDENTITY CHECK ---
|
||||
shadow_stmt = select(Person).where(
|
||||
and_(
|
||||
Person.last_name == kyc_in.last_name if hasattr(kyc_in, "last_name") else Person.last_name == p.last_name,
|
||||
Person.first_name == kyc_in.first_name if hasattr(kyc_in, "first_name") else Person.first_name == p.first_name,
|
||||
Person.birth_date == kyc_in.birth_date,
|
||||
Person.id != p.id # Ne a jelenlegit találja meg
|
||||
)
|
||||
)
|
||||
if kyc_in.birth_date:
|
||||
shadow_person = (await db.execute(shadow_stmt)).scalar_one_or_none()
|
||||
else:
|
||||
shadow_person = None
|
||||
|
||||
if shadow_person:
|
||||
logger.info(f"Shadow Identity megtalálva a {user.id} userhez: Person ID {shadow_person.id}")
|
||||
user.person_id = shadow_person.id
|
||||
|
||||
# Frissítjük a megtalált Person rekordot a KYC adatokkal
|
||||
shadow_person.mothers_last_name = kyc_in.mothers_last_name
|
||||
shadow_person.mothers_first_name = kyc_in.mothers_first_name
|
||||
shadow_person.birth_place = kyc_in.birth_place
|
||||
shadow_person.phone = kyc_in.phone_number
|
||||
shadow_person.address_id = addr_id
|
||||
shadow_person.identity_docs = jsonable_encoder(kyc_in.identity_docs)
|
||||
shadow_person.is_active = True
|
||||
|
||||
# Inaktiváljuk/töröljük a megárvult eredeti Person-t
|
||||
p.is_active = False
|
||||
p.is_ghost = True
|
||||
|
||||
p = shadow_person
|
||||
else:
|
||||
p.mothers_last_name = kyc_in.mothers_last_name
|
||||
p.mothers_first_name = kyc_in.mothers_first_name
|
||||
p.birth_place = kyc_in.birth_place
|
||||
p.birth_date = kyc_in.birth_date
|
||||
p.phone = kyc_in.phone_number
|
||||
p.address_id = addr_id
|
||||
p.identity_docs = jsonable_encoder(kyc_in.identity_docs)
|
||||
p.is_active = True
|
||||
# --- SHADOW CHECK VÉGE ---
|
||||
"""
|
||||
|
||||
old_logic = """ # Person adatok dúsítása
|
||||
p = user.person
|
||||
p.mothers_last_name = kyc_in.mothers_last_name
|
||||
p.mothers_first_name = kyc_in.mothers_first_name
|
||||
p.birth_place = kyc_in.birth_place
|
||||
p.birth_date = kyc_in.birth_date
|
||||
p.phone = kyc_in.phone_number
|
||||
p.address_id = addr_id
|
||||
p.identity_docs = jsonable_encoder(kyc_in.identity_docs)
|
||||
p.is_active = True"""
|
||||
|
||||
if old_logic in content:
|
||||
content = content.replace(old_logic, shadow_logic)
|
||||
with open('backend/app/services/auth_service.py', 'w') as f:
|
||||
f.write(content)
|
||||
print("Patched auth_service.py")
|
||||
else:
|
||||
print("Could not find the target code in auth_service.py")
|
||||
103
tests/archive/patch_auth_service_fix.py.old
Normal file
103
tests/archive/patch_auth_service_fix.py.old
Normal file
@@ -0,0 +1,103 @@
|
||||
import re
|
||||
|
||||
with open('backend/app/services/auth_service.py', 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
bad_logic = """ p = user.person
|
||||
|
||||
# --- SHADOW IDENTITY CHECK ---
|
||||
shadow_stmt = select(Person).where(
|
||||
and_(
|
||||
Person.last_name == kyc_in.last_name if hasattr(kyc_in, "last_name") else Person.last_name == p.last_name,
|
||||
Person.first_name == kyc_in.first_name if hasattr(kyc_in, "first_name") else Person.first_name == p.first_name,
|
||||
Person.birth_date == kyc_in.birth_date,
|
||||
Person.id != p.id # Ne a jelenlegit találja meg
|
||||
)
|
||||
)
|
||||
if kyc_in.birth_date:
|
||||
shadow_person = (await db.execute(shadow_stmt)).scalar_one_or_none()
|
||||
else:
|
||||
shadow_person = None
|
||||
|
||||
if shadow_person:
|
||||
logger.info(f"Shadow Identity megtalálva a {user.id} userhez: Person ID {shadow_person.id}")
|
||||
user.person_id = shadow_person.id
|
||||
|
||||
# Frissítjük a megtalált Person rekordot a KYC adatokkal
|
||||
shadow_person.mothers_last_name = kyc_in.mothers_last_name
|
||||
shadow_person.mothers_first_name = kyc_in.mothers_first_name
|
||||
shadow_person.birth_place = kyc_in.birth_place
|
||||
shadow_person.phone = kyc_in.phone_number
|
||||
shadow_person.address_id = addr_id
|
||||
shadow_person.identity_docs = jsonable_encoder(kyc_in.identity_docs)
|
||||
shadow_person.is_active = True
|
||||
|
||||
# Inaktiváljuk/töröljük a megárvult eredeti Person-t
|
||||
p.is_active = False
|
||||
p.is_ghost = True
|
||||
|
||||
p = shadow_person
|
||||
else:
|
||||
p.mothers_last_name = kyc_in.mothers_last_name
|
||||
p.mothers_first_name = kyc_in.mothers_first_name
|
||||
p.birth_place = kyc_in.birth_place
|
||||
p.birth_date = kyc_in.birth_date
|
||||
p.phone = kyc_in.phone_number
|
||||
p.address_id = addr_id
|
||||
p.identity_docs = jsonable_encoder(kyc_in.identity_docs)
|
||||
p.is_active = True
|
||||
# --- SHADOW CHECK VÉGE ---"""
|
||||
|
||||
good_logic = """ # Person adatok dúsítása
|
||||
p = user.person
|
||||
|
||||
# --- SHADOW IDENTITY CHECK ---
|
||||
if kyc_in.birth_date:
|
||||
shadow_stmt = select(Person).where(
|
||||
and_(
|
||||
Person.last_name == p.last_name,
|
||||
Person.first_name == p.first_name,
|
||||
Person.birth_date == kyc_in.birth_date,
|
||||
Person.id != p.id # Ne a jelenlegit találja meg
|
||||
)
|
||||
)
|
||||
shadow_person = (await db.execute(shadow_stmt)).scalar_one_or_none()
|
||||
else:
|
||||
shadow_person = None
|
||||
|
||||
if shadow_person:
|
||||
logger.info(f"Shadow Identity megtalálva a {user.id} userhez: Person ID {shadow_person.id}")
|
||||
user.person_id = shadow_person.id
|
||||
|
||||
# Frissítjük a megtalált Person rekordot a KYC adatokkal
|
||||
shadow_person.mothers_last_name = kyc_in.mothers_last_name
|
||||
shadow_person.mothers_first_name = kyc_in.mothers_first_name
|
||||
shadow_person.birth_place = kyc_in.birth_place
|
||||
shadow_person.phone = kyc_in.phone_number
|
||||
shadow_person.address_id = addr_id
|
||||
shadow_person.identity_docs = jsonable_encoder(kyc_in.identity_docs)
|
||||
shadow_person.is_active = True
|
||||
|
||||
# Inaktiváljuk/töröljük a megárvult eredeti Person-t
|
||||
p.is_active = False
|
||||
p.is_ghost = True
|
||||
|
||||
p = shadow_person
|
||||
else:
|
||||
p.mothers_last_name = kyc_in.mothers_last_name
|
||||
p.mothers_first_name = kyc_in.mothers_first_name
|
||||
p.birth_place = kyc_in.birth_place
|
||||
p.birth_date = kyc_in.birth_date
|
||||
p.phone = kyc_in.phone_number
|
||||
p.address_id = addr_id
|
||||
p.identity_docs = jsonable_encoder(kyc_in.identity_docs)
|
||||
p.is_active = True
|
||||
# --- SHADOW CHECK VÉGE ---"""
|
||||
|
||||
if bad_logic in content:
|
||||
content = content.replace(bad_logic, good_logic)
|
||||
with open('backend/app/services/auth_service.py', 'w') as f:
|
||||
f.write(content)
|
||||
print("Fixed patch auth_service.py")
|
||||
else:
|
||||
print("Could not find the target code in auth_service.py to fix")
|
||||
41
tests/archive/patch_test.py.old
Normal file
41
tests/archive/patch_test.py.old
Normal file
@@ -0,0 +1,41 @@
|
||||
with open("backend/test_invitation_e2e.py", "r") as f:
|
||||
code = f.read()
|
||||
|
||||
# Eltávolítjuk a delete részt
|
||||
code = code.replace(""" emails = ["owner@test.com", "existing@test.com", "newbie@test.com", "shadow@test.com"]
|
||||
for email in emails:
|
||||
stmt = select(User).where(User.email == email)
|
||||
user = (await db.execute(stmt)).scalar_one_or_none()
|
||||
if user:
|
||||
await db.delete(user)
|
||||
|
||||
shadow_person_stmt = select(Person).where(Person.last_name == "ShadowBéla")
|
||||
for p in (await db.execute(shadow_person_stmt)).scalars():
|
||||
await db.delete(p)
|
||||
|
||||
# Töröljük a korábbi tokeneket, amik a newbie@test.com-ra szólnak
|
||||
stmt_token = select(VerificationToken).where(VerificationToken.token_type == "org_invite")
|
||||
for t in (await db.execute(stmt_token)).scalars():
|
||||
if t.extra_data and t.extra_data.get("email") == "newbie@test.com":
|
||||
await db.delete(t)
|
||||
|
||||
await db.commit()""", "")
|
||||
|
||||
# Használjunk UUID-t az email címekhez
|
||||
code = code.replace("owner@test.com", f"owner_{uuid.uuid4().hex[:6]}@test.com")
|
||||
code = code.replace("existing@test.com", f"existing_{uuid.uuid4().hex[:6]}@test.com")
|
||||
code = code.replace("newbie@test.com", f"newbie_{uuid.uuid4().hex[:6]}@test.com")
|
||||
code = code.replace("shadow@test.com", f"shadow_{uuid.uuid4().hex[:6]}@test.com")
|
||||
code = code.replace("ShadowBéla", f"ShadowBéla_{uuid.uuid4().hex[:6]}")
|
||||
|
||||
# Fájl mentése UUID generálással
|
||||
import uuid
|
||||
random_suffix = uuid.uuid4().hex[:6]
|
||||
code = code.replace("owner_", f"owner_{random_suffix}_")
|
||||
code = code.replace("existing_", f"existing_{random_suffix}_")
|
||||
code = code.replace("newbie_", f"newbie_{random_suffix}_")
|
||||
code = code.replace("shadow_", f"shadow_{random_suffix}_")
|
||||
code = code.replace("ShadowBéla_", f"ShadowBéla_{random_suffix}_")
|
||||
|
||||
with open("backend/test_invitation_e2e.py", "w") as f:
|
||||
f.write("import uuid\n" + code)
|
||||
108
tests/archive/test_asset_e2e_direct.py.old
Normal file
108
tests/archive/test_asset_e2e_direct.py.old
Normal file
@@ -0,0 +1,108 @@
|
||||
import asyncio
|
||||
import httpx
|
||||
from sqlalchemy import select, delete
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.identity import User
|
||||
from app.models.marketplace.organization import Organization, Branch
|
||||
from app.models.vehicle.asset import Asset
|
||||
from app.models.vehicle.vehicle_definitions import VehicleModelDefinition
|
||||
from app.core.security import create_tokens
|
||||
|
||||
async def setup_test_data():
|
||||
async with AsyncSessionLocal() as db:
|
||||
user1_id = 2
|
||||
user2_id = 3
|
||||
org_id = 1
|
||||
|
||||
# Clean old test data
|
||||
from app.models.vehicle.asset import AssetAssignment
|
||||
assets_to_delete = (await db.execute(select(Asset).where(Asset.license_plate.in_(["TEST-000", "DRAFT-000", "OTHER-000"])))).scalars().all()
|
||||
for a in assets_to_delete:
|
||||
await db.execute(delete(AssetAssignment).where(AssetAssignment.asset_id == a.id))
|
||||
await db.execute(delete(Asset).where(Asset.license_plate.in_(["TEST-000", "DRAFT-000", "OTHER-000"])))
|
||||
await db.commit()
|
||||
|
||||
# Ensure main branch exists for org 1
|
||||
branch_stmt = select(Branch).where(Branch.organization_id == org_id, Branch.is_main == True)
|
||||
branch = (await db.execute(branch_stmt)).scalar()
|
||||
|
||||
token1, _ = create_tokens(data={"sub": str(user1_id)})
|
||||
token2, _ = create_tokens(data={"sub": str(user2_id)})
|
||||
|
||||
return token1, token2, org_id, branch.id
|
||||
|
||||
async def run_tests():
|
||||
print("--- SETUP ---")
|
||||
result = await setup_test_data()
|
||||
if not result: return
|
||||
token1, token2, org_id, branch_id = result
|
||||
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": "TESTVIN1111111111",
|
||||
"license_plate": "TEST-000",
|
||||
"brand": "Ford",
|
||||
"model": "Focus",
|
||||
"year_of_manufacture": 2018,
|
||||
"organization_id": org_id,
|
||||
"vehicle_class": "car",
|
||||
"fuel_type": "petrol"
|
||||
}
|
||||
resp1 = await client.post("/api/v1/assets/vehicles", json=payload1, headers=headers1)
|
||||
print(f"Status: {resp1.status_code}")
|
||||
try:
|
||||
data1 = resp1.json()
|
||||
if resp1.status_code == 201:
|
||||
assert data1["catalog_id"] > 0, f"Matcher failed: got None"
|
||||
assert data1["branch_id"] == str(branch_id), f"Branch failed: expected {branch_id}, got {data1.get('branch_id')}"
|
||||
print(f"-> SUCCESS: Matcher assigned catalog ({data1['catalog_id']}) and Main Branch assigned.")
|
||||
else:
|
||||
print(f"Failed with {data1}")
|
||||
except Exception as e:
|
||||
print(f"-> FAILED: {e}")
|
||||
|
||||
print("\n--- TEST 2: DRAFT / INCOMPLETE TEST ---")
|
||||
payload2 = {
|
||||
"license_plate": "DRAFT-000",
|
||||
"brand": "Ismeretlen",
|
||||
"organization_id": org_id
|
||||
}
|
||||
resp2 = await client.post("/api/v1/assets/vehicles", json=payload2, headers=headers1)
|
||||
print(f"Status: {resp2.status_code}")
|
||||
try:
|
||||
data2 = resp2.json()
|
||||
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.")
|
||||
else:
|
||||
print(f"Failed with {data2}")
|
||||
except Exception as e:
|
||||
print(f"-> FAILED: {e}")
|
||||
|
||||
print("\n--- TEST 3: OWNERSHIP TRANSFER TEST ---")
|
||||
payload3 = {
|
||||
"vin": "TESTVIN1111111111",
|
||||
"license_plate": "OTHER-000",
|
||||
"brand": "Ford",
|
||||
"model": "Focus",
|
||||
"organization_id": org_id
|
||||
}
|
||||
resp3 = await client.post("/api/v1/assets/vehicles", json=payload3, headers=headers2)
|
||||
print(f"Status: {resp3.status_code}")
|
||||
try:
|
||||
data3 = resp3.json()
|
||||
if resp3.status_code == 202:
|
||||
print("-> SUCCESS: VIN collision detected (transfer_pending).")
|
||||
else:
|
||||
print(f"Failed with {data3}")
|
||||
except Exception as e:
|
||||
print(f"-> FAILED: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(run_tests())
|
||||
128
tests/archive/test_asset_e2e_fetch.py.old
Normal file
128
tests/archive/test_asset_e2e_fetch.py.old
Normal file
@@ -0,0 +1,128 @@
|
||||
import asyncio
|
||||
import httpx
|
||||
from sqlalchemy import select, delete
|
||||
from sqlalchemy.orm import selectinload
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.identity import User
|
||||
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
|
||||
|
||||
async def setup_test_data():
|
||||
async with AsyncSessionLocal() as db:
|
||||
# Just find any 2 users that belong to ANY organization
|
||||
stmt = select(OrganizationMember).limit(2)
|
||||
members = (await db.execute(stmt)).scalars().all()
|
||||
if not members:
|
||||
print("No org members found")
|
||||
return None
|
||||
|
||||
user1_id = members[0].user_id
|
||||
org_id = members[0].organization_id
|
||||
|
||||
user2_id = members[1].user_id if len(members)>1 else user1_id
|
||||
|
||||
# Find or create branch
|
||||
branch_stmt = select(Branch).where(Branch.organization_id == org_id, Branch.is_main == True)
|
||||
branch = (await db.execute(branch_stmt)).scalar()
|
||||
if not branch:
|
||||
branch = Branch(organization_id=org_id, name="Test Main Branch", is_main=True)
|
||||
db.add(branch)
|
||||
await db.flush()
|
||||
|
||||
# Clean old 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.commit()
|
||||
|
||||
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()
|
||||
|
||||
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 ---")
|
||||
result = await setup_test_data()
|
||||
if not result:
|
||||
return
|
||||
token1, token2, org_id, branch_id, model_id = result
|
||||
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())
|
||||
58
tests/archive/test_catalog_only.py.old
Normal file
58
tests/archive/test_catalog_only.py.old
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test catalog filtering directly via AssetService.
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
sys.path.insert(0, '/app')
|
||||
|
||||
from app.db.session import async_sessionmaker
|
||||
from app.services.asset_service import AssetService
|
||||
|
||||
async def test():
|
||||
async_session = async_sessionmaker()
|
||||
async with async_session() as session:
|
||||
async with session.begin():
|
||||
# Get makes
|
||||
makes = await AssetService.get_makes(session)
|
||||
print(f"Total makes: {len(makes)}")
|
||||
if not makes:
|
||||
print("No makes in database")
|
||||
return
|
||||
test_make = makes[0]
|
||||
print(f"Testing with make: {test_make}")
|
||||
|
||||
# Get all models
|
||||
models_all = await AssetService.get_models(session, test_make)
|
||||
print(f"All models for {test_make}: {len(models_all)}")
|
||||
|
||||
# Get filtered by passenger_car
|
||||
models_car = await AssetService.get_models(session, test_make, 'passenger_car')
|
||||
print(f"Models filtered by 'passenger_car': {len(models_car)}")
|
||||
|
||||
# Get filtered by motorcycle
|
||||
models_moto = await AssetService.get_models(session, test_make, 'motorcycle')
|
||||
print(f"Models filtered by 'motorcycle': {len(models_moto)}")
|
||||
|
||||
# Verify filtering works
|
||||
if models_car and len(models_car) <= len(models_all):
|
||||
print("✅ PASS: Car filter returns subset or equal")
|
||||
else:
|
||||
print("⚠ WARNING: Car filter anomaly")
|
||||
|
||||
# Check if there's any difference
|
||||
if models_car != models_all:
|
||||
print("✅ PASS: Filtering actually changes results")
|
||||
else:
|
||||
print("⚠ WARNING: Filtering returns same results (maybe no vehicle_class data)")
|
||||
|
||||
# Print a few examples
|
||||
if models_all:
|
||||
print(f"Sample models: {models_all[:3]}")
|
||||
if models_car:
|
||||
print(f"Sample car models: {models_car[:3]}")
|
||||
if models_moto:
|
||||
print(f"Sample motorcycle models: {models_moto[:3]}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test())
|
||||
71
tests/archive/test_check_response.py.old
Normal file
71
tests/archive/test_check_response.py.old
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Check the full response from organization switch.
|
||||
"""
|
||||
|
||||
import json
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
|
||||
API_BASE = "http://sf_api:8000/api/v1"
|
||||
EMAIL = "tester_pro@profibot.hu"
|
||||
PASSWORD = "Password123!"
|
||||
|
||||
# Login
|
||||
print("Logging in...")
|
||||
data = urllib.parse.urlencode({
|
||||
'username': EMAIL,
|
||||
'password': PASSWORD
|
||||
}).encode('utf-8')
|
||||
|
||||
req = urllib.request.Request(f"{API_BASE}/auth/login", data=data, method='POST')
|
||||
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
response_data = json.loads(response.read().decode('utf-8'))
|
||||
token = response_data.get('access_token')
|
||||
print(f"Token: {token[:30]}...")
|
||||
|
||||
# Try switch with org_id
|
||||
payload = {"org_id": 21}
|
||||
print(f"\nTrying switch with payload: {payload}")
|
||||
data = json.dumps(payload).encode('utf-8')
|
||||
req = urllib.request.Request(
|
||||
f"{API_BASE}/users/me/active-organization",
|
||||
data=data,
|
||||
method='PATCH',
|
||||
headers={
|
||||
'Authorization': f'Bearer {token}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as resp:
|
||||
print(f"Success! Status: {resp.status}")
|
||||
full_response = resp.read().decode('utf-8')
|
||||
print(f"Full response ({len(full_response)} chars):")
|
||||
print(full_response)
|
||||
|
||||
# Parse and check structure
|
||||
parsed = json.loads(full_response)
|
||||
print(f"\nResponse keys: {list(parsed.keys())}")
|
||||
if 'access_token' in parsed:
|
||||
print(f"✅ access_token found: {parsed['access_token'][:30]}...")
|
||||
else:
|
||||
print("❌ No access_token in response")
|
||||
|
||||
if 'user' in parsed:
|
||||
print(f"✅ user found in response")
|
||||
else:
|
||||
print("❌ No user in response")
|
||||
|
||||
except urllib.error.HTTPError as e:
|
||||
print(f"HTTP Error {e.code}: {e.reason}")
|
||||
print(f"Response: {e.read().decode('utf-8')}")
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Login error: {e}")
|
||||
62
tests/archive/test_debug_switch.py.old
Normal file
62
tests/archive/test_debug_switch.py.old
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Debug the organization switch error.
|
||||
"""
|
||||
|
||||
import json
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
|
||||
API_BASE = "http://sf_api:8000/api/v1"
|
||||
EMAIL = "tester_pro@profibot.hu"
|
||||
PASSWORD = "Password123!"
|
||||
|
||||
# Login
|
||||
print("Logging in...")
|
||||
data = urllib.parse.urlencode({
|
||||
'username': EMAIL,
|
||||
'password': PASSWORD
|
||||
}).encode('utf-8')
|
||||
|
||||
req = urllib.request.Request(f"{API_BASE}/auth/login", data=data, method='POST')
|
||||
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
response_data = json.loads(response.read().decode('utf-8'))
|
||||
token = response_data.get('access_token')
|
||||
print(f"Token: {token[:30]}...")
|
||||
|
||||
# Try switch with different payload formats
|
||||
test_payloads = [
|
||||
{"organization_id": 21},
|
||||
{"organization_id": "21"},
|
||||
{"org_id": 21},
|
||||
{"id": 21}
|
||||
]
|
||||
|
||||
for payload in test_payloads:
|
||||
print(f"\nTrying payload: {payload}")
|
||||
data = json.dumps(payload).encode('utf-8')
|
||||
req = urllib.request.Request(
|
||||
f"{API_BASE}/users/me/active-organization",
|
||||
data=data,
|
||||
method='PATCH',
|
||||
headers={
|
||||
'Authorization': f'Bearer {token}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as resp:
|
||||
print(f"Success! Status: {resp.status}")
|
||||
print(f"Response: {resp.read().decode('utf-8')[:200]}")
|
||||
except urllib.error.HTTPError as e:
|
||||
print(f"HTTP Error {e.code}: {e.reason}")
|
||||
print(f"Response: {e.read().decode('utf-8')}")
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Login error: {e}")
|
||||
92
tests/archive/test_decode_token.py.old
Normal file
92
tests/archive/test_decode_token.py.old
Normal file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Decode the token to check scope_id.
|
||||
"""
|
||||
|
||||
import json
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import base64
|
||||
|
||||
API_BASE = "http://sf_api:8000/api/v1"
|
||||
EMAIL = "tester_pro@profibot.hu"
|
||||
PASSWORD = "Password123!"
|
||||
|
||||
def decode_jwt(token):
|
||||
"""Decode JWT token to get payload"""
|
||||
try:
|
||||
parts = token.split('.')
|
||||
if len(parts) == 3:
|
||||
payload = parts[1]
|
||||
# Add padding if needed
|
||||
padding = 4 - len(payload) % 4
|
||||
if padding != 4:
|
||||
payload += '=' * padding
|
||||
decoded = base64.b64decode(payload)
|
||||
return json.loads(decoded)
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not decode token: {e}")
|
||||
return {}
|
||||
|
||||
# Login
|
||||
print("Logging in...")
|
||||
data = urllib.parse.urlencode({
|
||||
'username': EMAIL,
|
||||
'password': PASSWORD
|
||||
}).encode('utf-8')
|
||||
|
||||
req = urllib.request.Request(f"{API_BASE}/auth/login", data=data, method='POST')
|
||||
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
response_data = json.loads(response.read().decode('utf-8'))
|
||||
token = response_data.get('access_token')
|
||||
print(f"Initial token: {token[:30]}...")
|
||||
|
||||
# Decode initial token
|
||||
initial_decoded = decode_jwt(token)
|
||||
print(f"Initial token payload:")
|
||||
for key, value in initial_decoded.items():
|
||||
print(f" {key}: {value}")
|
||||
|
||||
# Try switch with org_id
|
||||
payload = {"org_id": 21}
|
||||
print(f"\n🔄 Switching to org_id 21...")
|
||||
data = json.dumps(payload).encode('utf-8')
|
||||
req = urllib.request.Request(
|
||||
f"{API_BASE}/users/me/active-organization",
|
||||
data=data,
|
||||
method='PATCH',
|
||||
headers={
|
||||
'Authorization': f'Bearer {token}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
)
|
||||
|
||||
with urllib.request.urlopen(req) as resp:
|
||||
switch_response = json.loads(resp.read().decode('utf-8'))
|
||||
new_token = switch_response.get('access_token')
|
||||
|
||||
if new_token:
|
||||
print(f"✅ New token received: {new_token[:30]}...")
|
||||
|
||||
# Decode new token
|
||||
new_decoded = decode_jwt(new_token)
|
||||
print(f"New token payload:")
|
||||
for key, value in new_decoded.items():
|
||||
print(f" {key}: {value}")
|
||||
|
||||
print(f"\n🔍 Comparison:")
|
||||
print(f" Initial scope_id: {initial_decoded.get('scope_id')}")
|
||||
print(f" New scope_id: {new_decoded.get('scope_id')}")
|
||||
|
||||
if new_decoded.get('scope_id') != initial_decoded.get('scope_id'):
|
||||
print("✅ Scope ID changed in token!")
|
||||
else:
|
||||
print("⚠️ Scope ID unchanged in token")
|
||||
else:
|
||||
print("❌ No new token in response")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
265
tests/archive/test_final_verification.py.old
Normal file
265
tests/archive/test_final_verification.py.old
Normal file
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Final verification test using only standard library.
|
||||
Tests the complete organization switching flow.
|
||||
"""
|
||||
|
||||
import json
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import base64
|
||||
import sys
|
||||
|
||||
API_BASE = "http://sf_api:8000/api/v1"
|
||||
EMAIL = "tester_pro@profibot.hu"
|
||||
PASSWORD = "Password123!"
|
||||
|
||||
def make_request(method, endpoint, token=None, data=None):
|
||||
"""Make HTTP request using urllib"""
|
||||
url = f"{API_BASE}{endpoint}"
|
||||
headers = {}
|
||||
|
||||
if token:
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
if data and method in ["POST", "PATCH", "PUT"]:
|
||||
data = json.dumps(data).encode('utf-8')
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
req = urllib.request.Request(url, data=data, headers=headers, method=method)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
response_data = response.read().decode('utf-8')
|
||||
return {
|
||||
"error": False,
|
||||
"status": response.status,
|
||||
"data": json.loads(response_data) if response_data else {}
|
||||
}
|
||||
except urllib.error.HTTPError as e:
|
||||
error_data = e.read().decode('utf-8') if e.read() else ""
|
||||
return {
|
||||
"error": True,
|
||||
"status": e.code,
|
||||
"data": json.loads(error_data) if error_data else {"detail": str(e)}
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
"error": True,
|
||||
"status": 0,
|
||||
"data": {"detail": str(e)}
|
||||
}
|
||||
|
||||
def login():
|
||||
"""Login and return token"""
|
||||
print("🔐 Logging in...")
|
||||
|
||||
data = urllib.parse.urlencode({
|
||||
'username': EMAIL,
|
||||
'password': PASSWORD
|
||||
}).encode('utf-8')
|
||||
|
||||
req = urllib.request.Request(f"{API_BASE}/auth/login", data=data, method='POST')
|
||||
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
response_data = json.loads(response.read().decode('utf-8'))
|
||||
token = response_data.get('access_token')
|
||||
if token:
|
||||
print(f"✅ Login successful")
|
||||
return token
|
||||
else:
|
||||
print(f"❌ No token in response")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Login failed: {e}")
|
||||
return None
|
||||
|
||||
def decode_jwt(token):
|
||||
"""Decode JWT token to get payload"""
|
||||
try:
|
||||
parts = token.split('.')
|
||||
if len(parts) == 3:
|
||||
payload = parts[1]
|
||||
# Add padding if needed
|
||||
padding = 4 - len(payload) % 4
|
||||
if padding != 4:
|
||||
payload += '=' * padding
|
||||
decoded = base64.b64decode(payload)
|
||||
return json.loads(decoded)
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not decode token: {e}")
|
||||
return {}
|
||||
|
||||
def main():
|
||||
print("=" * 60)
|
||||
print("🧪 FINAL VERIFICATION TEST")
|
||||
print("=" * 60)
|
||||
|
||||
# 1. Login
|
||||
token = login()
|
||||
if not token:
|
||||
print("❌ Cannot proceed without login")
|
||||
return 1
|
||||
|
||||
print(f"Token: {token[:30]}...")
|
||||
|
||||
# 2. Get user info
|
||||
print("\n👤 Getting user info...")
|
||||
user_result = make_request("GET", "/users/me", token)
|
||||
if user_result["error"]:
|
||||
print(f"❌ Failed to get user info: {user_result['data']}")
|
||||
return 1
|
||||
|
||||
user_data = user_result["data"]
|
||||
print(f"✅ User: {user_data.get('email')}")
|
||||
print(f" ID: {user_data.get('id')}, Role: {user_data.get('role')}")
|
||||
print(f" Scope ID: {user_data.get('scope_id')}")
|
||||
print(f" Active Org ID: {user_data.get('active_organization_id')}")
|
||||
print(f" Person ID: {user_data.get('person_id')}")
|
||||
|
||||
# 3. Get organizations
|
||||
print("\n🏢 Getting organizations...")
|
||||
orgs_result = make_request("GET", "/organizations/me", token)
|
||||
if orgs_result["error"]:
|
||||
print(f"❌ Failed to get organizations: {orgs_result['data']}")
|
||||
return 1
|
||||
|
||||
orgs = orgs_result["data"]
|
||||
print(f"✅ Found {len(orgs)} organizations:")
|
||||
|
||||
org_map = {}
|
||||
for org in orgs:
|
||||
org_id = org.get('id')
|
||||
org_name = org.get('name')
|
||||
org_type = org.get('org_type', 'UNKNOWN')
|
||||
org_map[org_type] = org_id
|
||||
print(f" - {org_type}: ID {org_id} - {org_name}")
|
||||
|
||||
# 4. Test organization switching
|
||||
print("\n🔄 Testing organization switching...")
|
||||
test_results = {}
|
||||
|
||||
for org_type, org_id in org_map.items():
|
||||
print(f"\n{'='*40}")
|
||||
print(f"Testing switch to {org_type} (ID: {org_id})")
|
||||
|
||||
# Switch organization
|
||||
switch_result = make_request("PATCH", "/users/me/active-organization", token,
|
||||
{"organization_id": org_id})
|
||||
|
||||
if switch_result["error"]:
|
||||
print(f"❌ Switch failed: {switch_result['data']}")
|
||||
test_results[org_type] = {"success": False, "error": switch_result['data']}
|
||||
continue
|
||||
|
||||
response_data = switch_result["data"]
|
||||
print(f"✅ Switch response received")
|
||||
|
||||
# Check for new token
|
||||
new_token = response_data.get('access_token')
|
||||
if new_token:
|
||||
print(f"✅ New token received: {new_token[:30]}...")
|
||||
print(f" Token changed: {new_token != token}")
|
||||
|
||||
# Decode new token
|
||||
decoded = decode_jwt(new_token)
|
||||
print(f"🔍 Decoded token:")
|
||||
print(f" Scope ID: {decoded.get('scope_id')}")
|
||||
print(f" Scope Level: {decoded.get('scope_level')}")
|
||||
print(f" Role: {decoded.get('role')}")
|
||||
|
||||
# Update token
|
||||
token = new_token
|
||||
|
||||
# Get updated user info
|
||||
user_result = make_request("GET", "/users/me", token)
|
||||
if not user_result["error"]:
|
||||
updated_user = user_result["data"]
|
||||
print(f"📋 Updated scope ID: {updated_user.get('scope_id')}")
|
||||
|
||||
# Get vehicles in new scope
|
||||
vehicles_result = make_request("GET", "/users/me/assets", token)
|
||||
if not vehicles_result["error"]:
|
||||
vehicles = vehicles_result["data"]
|
||||
print(f"🚗 Vehicles in scope: {len(vehicles)}")
|
||||
for v in vehicles[:3]: # Show first 3
|
||||
print(f" - {v.get('vrm')}: {v.get('make')} {v.get('model')}")
|
||||
if len(vehicles) > 3:
|
||||
print(f" ... and {len(vehicles) - 3} more")
|
||||
|
||||
test_results[org_type] = {
|
||||
"success": True,
|
||||
"scope_id": decoded.get('scope_id'),
|
||||
"got_new_token": True
|
||||
}
|
||||
else:
|
||||
print(f"⚠️ No new token in response")
|
||||
test_results[org_type] = {
|
||||
"success": True,
|
||||
"got_new_token": False
|
||||
}
|
||||
|
||||
# 5. Summary
|
||||
print(f"\n{'='*60}")
|
||||
print("📊 TEST SUMMARY")
|
||||
print(f"{'='*60}")
|
||||
|
||||
all_passed = True
|
||||
token_refresh_working = False
|
||||
|
||||
for org_type, result in test_results.items():
|
||||
if result["success"]:
|
||||
status = "✅ PASSED"
|
||||
if result.get("got_new_token"):
|
||||
token_refresh_working = True
|
||||
status += " (token refresh ✓)"
|
||||
else:
|
||||
status = "❌ FAILED"
|
||||
all_passed = False
|
||||
|
||||
print(f"{org_type:20} {status}")
|
||||
|
||||
# 6. Final verification
|
||||
print(f"\n{'='*40}")
|
||||
print("🔍 FINAL VERIFICATION")
|
||||
print(f"{'='*40}")
|
||||
|
||||
if all_passed:
|
||||
print("🎉 ALL TESTS PASSED!")
|
||||
|
||||
if token_refresh_working:
|
||||
print("✅ Token refresh is working correctly")
|
||||
print("✅ Frontend will receive new tokens when switching organizations")
|
||||
print("✅ Scope-based filtering is functional")
|
||||
else:
|
||||
print("⚠️ Tests passed but token refresh not confirmed")
|
||||
|
||||
# Database state verification
|
||||
print("\n📋 DATABASE STATE VERIFICATION:")
|
||||
print("1. ✅ tester_pro has person_id=29, user_id=28")
|
||||
print("2. ✅ Private Organization (ID 21) has owner_id=29")
|
||||
print("3. ✅ Alpha Organization (ID 26) has owner_id=29")
|
||||
print("4. ✅ Beta Organization (ID 27) has owner_id=29")
|
||||
print("5. ✅ Each organization has 1 branch")
|
||||
print("6. ✅ Vehicles distributed: AAA111 to Private, AAA111 to Alpha, AAA222 to Beta")
|
||||
print("7. ✅ Asset assignments created with proper UUIDs")
|
||||
print("8. ✅ Backend token refresh implemented")
|
||||
print("9. ✅ Frontend auth store updated to handle new tokens")
|
||||
|
||||
print(f"\n🎯 MISSION ACCOMPLISHED!")
|
||||
print("The strict 6-step lifecycle has been successfully implemented:")
|
||||
print("1. ✅ Document Intent & Check Existing System")
|
||||
print("2. ✅ Database Surgery (Fix/Create)")
|
||||
print("3. ✅ Backend Token Refresh & Frontend Wiring")
|
||||
print("4. ✅ Verification (Check)")
|
||||
print("5. ✅ Document Final State & Report Ready")
|
||||
|
||||
return 0
|
||||
else:
|
||||
print("❌ SOME TESTS FAILED")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
110
tests/archive/test_flow_simple.sh.old
Executable file
110
tests/archive/test_flow_simple.sh.old
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Simple test for organization switching flow
|
||||
# Uses curl to test the API endpoints
|
||||
|
||||
API_BASE="http://localhost:8000"
|
||||
EMAIL="tester_pro@profibot.hu"
|
||||
PASSWORD="Password123!"
|
||||
|
||||
echo "🧪 Testing Organization Switching Flow"
|
||||
echo "======================================"
|
||||
|
||||
# 1. Login
|
||||
echo -e "\n1. Logging in as $EMAIL..."
|
||||
LOGIN_RESPONSE=$(curl -s -X POST "$API_BASE/auth/login" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=$EMAIL&password=$PASSWORD")
|
||||
|
||||
ACCESS_TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.access_token // empty')
|
||||
|
||||
if [ -z "$ACCESS_TOKEN" ]; then
|
||||
echo "❌ Login failed"
|
||||
echo "Response: $LOGIN_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Login successful"
|
||||
echo "Token: ${ACCESS_TOKEN:0:30}..."
|
||||
|
||||
# 2. Get user info
|
||||
echo -e "\n2. Getting user info..."
|
||||
USER_INFO=$(curl -s -X GET "$API_BASE/users/me" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN")
|
||||
|
||||
echo "User info:"
|
||||
echo "$USER_INFO" | jq '{
|
||||
id: .id,
|
||||
email: .email,
|
||||
role: .role,
|
||||
scope_id: .scope_id,
|
||||
active_organization_id: .active_organization_id,
|
||||
person_id: .person_id
|
||||
}'
|
||||
|
||||
# 3. Get organizations
|
||||
echo -e "\n3. Getting user organizations..."
|
||||
ORGS=$(curl -s -X GET "$API_BASE/organizations/me" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN")
|
||||
|
||||
ORG_COUNT=$(echo "$ORGS" | jq 'length')
|
||||
echo "Found $ORG_COUNT organizations:"
|
||||
echo "$ORGS" | jq '.[] | {id: .id, name: .name, org_type: .org_type}'
|
||||
|
||||
# Extract organization IDs
|
||||
ORG_IDS=$(echo "$ORGS" | jq -r '.[].id')
|
||||
echo "Organization IDs: $ORG_IDS"
|
||||
|
||||
# 4. Test switching to each organization
|
||||
echo -e "\n4. Testing organization switching..."
|
||||
for ORG_ID in $ORG_IDS; do
|
||||
echo -e "\n🔄 Switching to organization ID: $ORG_ID"
|
||||
|
||||
SWITCH_RESPONSE=$(curl -s -X PATCH "$API_BASE/users/me/active-organization" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"organization_id\": $ORG_ID}")
|
||||
|
||||
echo "Switch response:"
|
||||
echo "$SWITCH_RESPONSE" | jq '.'
|
||||
|
||||
# Check if we got a new token
|
||||
NEW_TOKEN=$(echo "$SWITCH_RESPONSE" | jq -r '.access_token // empty')
|
||||
if [ -n "$NEW_TOKEN" ]; then
|
||||
echo "✅ Got new token: ${NEW_TOKEN:0:30}..."
|
||||
ACCESS_TOKEN="$NEW_TOKEN"
|
||||
|
||||
# Decode token to check scope
|
||||
echo "🔍 Decoded token payload:"
|
||||
PAYLOAD=$(echo "$NEW_TOKEN" | cut -d'.' -f2 | base64 -d 2>/dev/null || echo "{}")
|
||||
echo "$PAYLOAD" | jq '{scope_id: .scope_id, scope_level: .scope_level, role: .role}'
|
||||
else
|
||||
echo "⚠️ No new token in response"
|
||||
fi
|
||||
|
||||
# Get updated user info
|
||||
echo "📋 Updated user info:"
|
||||
UPDATED_INFO=$(curl -s -X GET "$API_BASE/users/me" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN")
|
||||
echo "$UPDATED_INFO" | jq '{scope_id: .scope_id, active_organization_id: .active_organization_id}'
|
||||
|
||||
# Get vehicles in current scope
|
||||
echo "🚗 Vehicles in current scope:"
|
||||
VEHICLES=$(curl -s -X GET "$API_BASE/users/me/assets" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN")
|
||||
VEHICLE_COUNT=$(echo "$VEHICLES" | jq 'length')
|
||||
echo "Count: $VEHICLE_COUNT"
|
||||
if [ "$VEHICLE_COUNT" -gt 0 ]; then
|
||||
echo "$VEHICLES" | jq '.[] | {id: .id, vrm: .vrm, make: .make, model: .model}'
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo -e "\n🎉 Test completed successfully!"
|
||||
echo "Summary:"
|
||||
echo "- Login: ✅"
|
||||
echo "- User info: ✅"
|
||||
echo "- Organizations: ✅ ($ORG_COUNT found)"
|
||||
echo "- Organization switching: ✅ (with token refresh)"
|
||||
echo "- Scope filtering: ✅ (vehicles filtered by organization)"
|
||||
130
tests/archive/test_integration.py.old
Normal file
130
tests/archive/test_integration.py.old
Normal file
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Integration test for the Smart Vehicle Registration fixes.
|
||||
Tests: login, catalog filtering, vehicle registration.
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, '/app')
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
from app.api.v1.api import api_router
|
||||
from fastapi import FastAPI
|
||||
from app.core.config import settings
|
||||
import json
|
||||
|
||||
app = FastAPI()
|
||||
app.include_router(api_router)
|
||||
client = TestClient(app)
|
||||
|
||||
def test_login():
|
||||
"""Login with tester_pro@profibot.hu and Password123!"""
|
||||
print("1. Testing login...")
|
||||
response = client.post("/auth/login", json={
|
||||
"email": "tester_pro@profibot.hu",
|
||||
"password": "Password123!"
|
||||
})
|
||||
if response.status_code != 200:
|
||||
print(f" ❌ Login failed: {response.status_code} {response.text}")
|
||||
return None
|
||||
token = response.json().get("access_token")
|
||||
print(f" ✅ Login successful, token: {token[:20]}...")
|
||||
return token
|
||||
|
||||
def test_catalog_makes(token):
|
||||
"""Test catalog makes endpoint with auth."""
|
||||
print("2. Testing catalog makes...")
|
||||
response = client.get("/catalog/makes", headers={"Authorization": f"Bearer {token}"})
|
||||
if response.status_code != 200:
|
||||
print(f" ❌ Makes failed: {response.status_code} {response.text}")
|
||||
return None
|
||||
makes = response.json()
|
||||
print(f" ✅ Makes retrieved: {len(makes)} items")
|
||||
return makes
|
||||
|
||||
def test_catalog_models_filter(token, make, vehicle_class):
|
||||
"""Test catalog models endpoint with vehicle_class filter."""
|
||||
print(f"3. Testing catalog models with make={make}, vehicle_class={vehicle_class}...")
|
||||
params = {"make": make}
|
||||
if vehicle_class:
|
||||
params["vehicle_class"] = vehicle_class
|
||||
response = client.get("/catalog/models", headers={"Authorization": f"Bearer {token}"}, params=params)
|
||||
if response.status_code != 200:
|
||||
print(f" ❌ Models failed: {response.status_code} {response.text}")
|
||||
return None
|
||||
models = response.json()
|
||||
print(f" ✅ Models retrieved: {len(models)} items")
|
||||
return models
|
||||
|
||||
def test_vehicle_registration(token, org_id=None):
|
||||
"""Test vehicle registration endpoint with a minimal payload."""
|
||||
print("4. Testing vehicle registration...")
|
||||
payload = {
|
||||
"license_plate": "TEST-123",
|
||||
"brand": "Toyota",
|
||||
"model": "Corolla",
|
||||
"vehicle_class": "passenger_car",
|
||||
"fuel_type": "petrol",
|
||||
"current_mileage": 50000,
|
||||
"status": "draft",
|
||||
"organization_id": org_id,
|
||||
"owner_org_id": org_id,
|
||||
"operator_org_id": org_id,
|
||||
}
|
||||
response = client.post("/assets/vehicles",
|
||||
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
|
||||
json=payload)
|
||||
if response.status_code not in (200, 201):
|
||||
print(f" ❌ Registration failed: {response.status_code} {response.text}")
|
||||
return None
|
||||
result = response.json()
|
||||
print(f" ✅ Vehicle registered: ID {result.get('id')}")
|
||||
return result
|
||||
|
||||
def main():
|
||||
print("=== Integration Test for Smart Vehicle Registration Fixes ===")
|
||||
token = test_login()
|
||||
if not token:
|
||||
print("❌ Test aborted due to login failure.")
|
||||
return
|
||||
|
||||
makes = test_catalog_makes(token)
|
||||
if not makes:
|
||||
print("❌ Test aborted due to catalog failure.")
|
||||
return
|
||||
|
||||
# Test filtering
|
||||
test_make = makes[0] if makes else "Toyota"
|
||||
models_all = test_catalog_models_filter(token, test_make, None)
|
||||
models_car = test_catalog_models_filter(token, test_make, "passenger_car")
|
||||
models_motorcycle = test_catalog_models_filter(token, test_make, "motorcycle")
|
||||
|
||||
# Compare counts
|
||||
if models_all and models_car:
|
||||
if len(models_car) <= len(models_all):
|
||||
print(" ✅ Filtering works (car count <= all count)")
|
||||
else:
|
||||
print(" ⚠ Filtering anomaly (car count > all count)")
|
||||
|
||||
# Test registration (requires organization ID, but we can try without)
|
||||
# First get user's organizations
|
||||
print("5. Fetching user organizations...")
|
||||
response = client.get("/organizations/my", headers={"Authorization": f"Bearer {token}"})
|
||||
if response.status_code == 200:
|
||||
orgs = response.json()
|
||||
if orgs:
|
||||
org_id = orgs[0].get("organization_id")
|
||||
print(f" Using organization ID: {org_id}")
|
||||
test_vehicle_registration(token, org_id)
|
||||
else:
|
||||
print(" No organizations, testing without org...")
|
||||
test_vehicle_registration(token, None)
|
||||
else:
|
||||
print(f" Could not fetch organizations: {response.status_code}")
|
||||
test_vehicle_registration(token, None)
|
||||
|
||||
print("=== Integration Test Completed ===")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
52
tests/archive/test_makes_filter.py.old
Normal file
52
tests/archive/test_makes_filter.py.old
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test the /catalog/makes endpoint with vehicle_class filtering.
|
||||
"""
|
||||
import asyncio
|
||||
import aiohttp
|
||||
import sys
|
||||
import os
|
||||
|
||||
async def test_makes_filter():
|
||||
# Use the internal API URL (within docker network)
|
||||
base_url = "http://sf_api:8000"
|
||||
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0ZXJfcHJvQHByb2ZpYm90Lmh1IiwiZXhwIjoxNzQzNDQwMDAwLCJpYXQiOjE3NDA4NDgwMDAsInNjb3BlIjoicGVyc29uYWwiLCJ1c2VyX2lkIjozMCwib3JnX2lkIjpudWxsfQ.dummy_token"
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
async with aiohttp.ClientSession(headers=headers) as session:
|
||||
# Test without vehicle_class (should return all makes)
|
||||
print("Testing /catalog/makes without vehicle_class...")
|
||||
async with session.get(f"{base_url}/api/v1/catalog/makes") as resp:
|
||||
print(f" Status: {resp.status}")
|
||||
if resp.status == 200:
|
||||
data = await resp.json()
|
||||
print(f" Makes count: {len(data)}")
|
||||
print(f" First 5 makes: {data[:5]}")
|
||||
else:
|
||||
print(f" Error: {await resp.text()}")
|
||||
|
||||
# Test with vehicle_class = 'motorcycle'
|
||||
print("\nTesting /catalog/makes with vehicle_class='motorcycle'...")
|
||||
async with session.get(f"{base_url}/api/v1/catalog/makes?vehicle_class=motorcycle") as resp:
|
||||
print(f" Status: {resp.status}")
|
||||
if resp.status == 200:
|
||||
data = await resp.json()
|
||||
print(f" Makes count: {len(data)}")
|
||||
print(f" Makes: {data}")
|
||||
else:
|
||||
print(f" Error: {await resp.text()}")
|
||||
|
||||
# Test with vehicle_class = 'passenger_car'
|
||||
print("\nTesting /catalog/makes with vehicle_class='passenger_car'...")
|
||||
async with session.get(f"{base_url}/api/v1/catalog/makes?vehicle_class=passenger_car") as resp:
|
||||
print(f" Status: {resp.status}")
|
||||
if resp.status == 200:
|
||||
data = await resp.json()
|
||||
print(f" Makes count: {len(data)}")
|
||||
print(f" First 5 makes: {data[:5]}")
|
||||
else:
|
||||
print(f" Error: {await resp.text()}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_makes_filter())
|
||||
177
tests/archive/test_minimal_verification.py.old
Normal file
177
tests/archive/test_minimal_verification.py.old
Normal file
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Minimal verification test - just test the core token refresh functionality.
|
||||
"""
|
||||
|
||||
import json
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import base64
|
||||
import sys
|
||||
|
||||
API_BASE = "http://sf_api:8000/api/v1"
|
||||
EMAIL = "tester_pro@profibot.hu"
|
||||
PASSWORD = "Password123!"
|
||||
|
||||
def make_request(method, endpoint, token=None, data=None):
|
||||
"""Make HTTP request using urllib"""
|
||||
url = f"{API_BASE}{endpoint}"
|
||||
headers = {}
|
||||
|
||||
if token:
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
if data and method in ["POST", "PATCH", "PUT"]:
|
||||
data = json.dumps(data).encode('utf-8')
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
req = urllib.request.Request(url, data=data, headers=headers, method=method)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
response_data = response.read().decode('utf-8')
|
||||
return {
|
||||
"error": False,
|
||||
"status": response.status,
|
||||
"data": json.loads(response_data) if response_data else {}
|
||||
}
|
||||
except urllib.error.HTTPError as e:
|
||||
error_data = e.read().decode('utf-8') if e.read() else ""
|
||||
return {
|
||||
"error": True,
|
||||
"status": e.code,
|
||||
"data": json.loads(error_data) if error_data else {"detail": str(e)}
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
"error": True,
|
||||
"status": 0,
|
||||
"data": {"detail": str(e)}
|
||||
}
|
||||
|
||||
def login():
|
||||
"""Login and return token"""
|
||||
print("🔐 Logging in...")
|
||||
|
||||
data = urllib.parse.urlencode({
|
||||
'username': EMAIL,
|
||||
'password': PASSWORD
|
||||
}).encode('utf-8')
|
||||
|
||||
req = urllib.request.Request(f"{API_BASE}/auth/login", data=data, method='POST')
|
||||
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
response_data = json.loads(response.read().decode('utf-8'))
|
||||
token = response_data.get('access_token')
|
||||
if token:
|
||||
print(f"✅ Login successful")
|
||||
return token
|
||||
else:
|
||||
print(f"❌ No token in response")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Login failed: {e}")
|
||||
return None
|
||||
|
||||
def decode_jwt(token):
|
||||
"""Decode JWT token to get payload"""
|
||||
try:
|
||||
parts = token.split('.')
|
||||
if len(parts) == 3:
|
||||
payload = parts[1]
|
||||
# Add padding if needed
|
||||
padding = 4 - len(payload) % 4
|
||||
if padding != 4:
|
||||
payload += '=' * padding
|
||||
decoded = base64.b64decode(payload)
|
||||
return json.loads(decoded)
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not decode token: {e}")
|
||||
return {}
|
||||
|
||||
def main():
|
||||
print("=" * 60)
|
||||
print("🧪 MINIMAL VERIFICATION TEST")
|
||||
print("=" * 60)
|
||||
|
||||
# 1. Login
|
||||
token = login()
|
||||
if not token:
|
||||
print("❌ Cannot proceed without login")
|
||||
return 1
|
||||
|
||||
print(f"Initial token: {token[:30]}...")
|
||||
|
||||
# Decode initial token
|
||||
initial_decoded = decode_jwt(token)
|
||||
print(f"Initial scope ID: {initial_decoded.get('scope_id')}")
|
||||
|
||||
# 2. Test switching to organization ID 21 (Private)
|
||||
print("\n🔄 Testing switch to Private Organization (ID: 21)...")
|
||||
switch_result = make_request("PATCH", "/users/me/active-organization", token,
|
||||
{"organization_id": 21})
|
||||
|
||||
if switch_result["error"]:
|
||||
print(f"❌ Switch failed: {switch_result['data']}")
|
||||
return 1
|
||||
|
||||
response_data = switch_result["data"]
|
||||
print(f"✅ Switch response received")
|
||||
|
||||
# Check for new token
|
||||
new_token = response_data.get('access_token')
|
||||
if new_token:
|
||||
print(f"✅ New token received: {new_token[:30]}...")
|
||||
print(f" Token changed: {new_token != token}")
|
||||
|
||||
# Decode new token
|
||||
decoded = decode_jwt(new_token)
|
||||
print(f"🔍 Decoded new token:")
|
||||
print(f" Scope ID: {decoded.get('scope_id')} (should be 21)")
|
||||
print(f" Scope Level: {decoded.get('scope_level')}")
|
||||
|
||||
if decoded.get('scope_id') == 21:
|
||||
print("✅ Scope ID updated correctly in token!")
|
||||
|
||||
# Test switching back to organization ID 15 (Corporate)
|
||||
print("\n🔄 Testing switch back to Corporate Organization (ID: 15)...")
|
||||
switch_back_result = make_request("PATCH", "/users/me/active-organization", new_token,
|
||||
{"organization_id": 15})
|
||||
|
||||
if not switch_back_result["error"]:
|
||||
switch_back_data = switch_back_result["data"]
|
||||
newer_token = switch_back_data.get('access_token')
|
||||
|
||||
if newer_token:
|
||||
print(f"✅ Another new token received: {newer_token[:30]}...")
|
||||
newer_decoded = decode_jwt(newer_token)
|
||||
print(f"🔍 Decoded token scope ID: {newer_decoded.get('scope_id')} (should be 15)")
|
||||
|
||||
if newer_decoded.get('scope_id') == 15:
|
||||
print("✅ Token refresh working correctly for both directions!")
|
||||
print("\n🎉 CORE FUNCTIONALITY VERIFIED!")
|
||||
print("✅ Backend token refresh is working")
|
||||
print("✅ Scope ID is updated in JWT token")
|
||||
print("✅ Frontend can extract and use new tokens")
|
||||
return 0
|
||||
else:
|
||||
print(f"❌ Scope ID not updated correctly: {newer_decoded.get('scope_id')}")
|
||||
return 1
|
||||
else:
|
||||
print("❌ No token in switch back response")
|
||||
return 1
|
||||
else:
|
||||
print(f"❌ Switch back failed: {switch_back_result['data']}")
|
||||
return 1
|
||||
else:
|
||||
print(f"❌ Scope ID not updated in token: {decoded.get('scope_id')}")
|
||||
return 1
|
||||
else:
|
||||
print("❌ No new token in response")
|
||||
print(f"Response: {response_data}")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
161
tests/archive/test_mvp.py.old
Normal file
161
tests/archive/test_mvp.py.old
Normal file
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MVP funkciók tesztelése - API szintű tesztek
|
||||
"""
|
||||
import sys
|
||||
import json
|
||||
import requests
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
BASE_URL = "http://192.168.100.10:8000/api/v1"
|
||||
HEADERS = {"Content-Type": "application/json"}
|
||||
|
||||
def print_response(response: requests.Response, description: str):
|
||||
"""Helper to print response details"""
|
||||
print(f"\n=== {description} ===")
|
||||
print(f"Status: {response.status_code}")
|
||||
try:
|
||||
print(f"Body: {response.json()}")
|
||||
except:
|
||||
print(f"Body (text): {response.text}")
|
||||
|
||||
def login(username: str, password: str) -> Optional[str]:
|
||||
"""Bejelentkezés és token lekérése"""
|
||||
url = f"{BASE_URL}/auth/login"
|
||||
payload = {
|
||||
"username": username,
|
||||
"password": password
|
||||
}
|
||||
try:
|
||||
response = requests.post(url, json=payload, headers=HEADERS, timeout=10)
|
||||
print_response(response, "Login")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
token = data.get("access_token")
|
||||
if token:
|
||||
print(f"Token received: {token[:20]}...")
|
||||
return token
|
||||
return None
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
print(f"Connection error: {e}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"Login error: {e}")
|
||||
return None
|
||||
|
||||
def test_vehicle_creation(token: str) -> Optional[str]:
|
||||
"""Jármű rögzítése"""
|
||||
url = f"{BASE_URL}/assets/vehicles"
|
||||
headers = HEADERS.copy()
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
payload = {
|
||||
"plate_number": "ABC-123",
|
||||
"vin": "1HGCM82633A123456",
|
||||
"make": "Honda",
|
||||
"model": "Accord",
|
||||
"year": 2020
|
||||
}
|
||||
|
||||
response = requests.post(url, json=payload, headers=headers, timeout=10)
|
||||
print_response(response, "Vehicle Creation")
|
||||
|
||||
if response.status_code in (200, 201):
|
||||
data = response.json()
|
||||
asset_id = data.get("asset_id")
|
||||
if asset_id:
|
||||
print(f"Vehicle created with asset_id: {asset_id}")
|
||||
return asset_id
|
||||
return None
|
||||
|
||||
def test_expense_creation(token: str, asset_id: str):
|
||||
"""Jármű költség rögzítése"""
|
||||
url = f"{BASE_URL}/expenses/"
|
||||
headers = HEADERS.copy()
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
payload = {
|
||||
"asset_id": asset_id,
|
||||
"cost_type": "fuel",
|
||||
"amount": 15000,
|
||||
"currency": "HUF",
|
||||
"odometer": 50000,
|
||||
"description": "Tankolás"
|
||||
}
|
||||
|
||||
response = requests.post(url, json=payload, headers=headers, timeout=10)
|
||||
print_response(response, "Expense Creation")
|
||||
|
||||
def test_service_search(token: str):
|
||||
"""Szervizpont keresés"""
|
||||
url = f"{BASE_URL}/services/search"
|
||||
headers = HEADERS.copy()
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
params = {"query": "autószerviz"}
|
||||
response = requests.get(url, params=params, headers=headers, timeout=10)
|
||||
print_response(response, "Service Search")
|
||||
|
||||
def test_gamification_stats(token: str):
|
||||
"""Gamification státusz lekérése"""
|
||||
url = f"{BASE_URL}/gamification/my-stats"
|
||||
headers = HEADERS.copy()
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
response = requests.get(url, headers=headers, timeout=10)
|
||||
print_response(response, "Gamification Stats")
|
||||
|
||||
def test_wallet_balance(token: str):
|
||||
"""Wallet egyenleg lekérése"""
|
||||
url = f"{BASE_URL}/users/me"
|
||||
headers = HEADERS.copy()
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
response = requests.get(url, headers=headers, timeout=10)
|
||||
print_response(response, "User Wallet Balance")
|
||||
|
||||
def main():
|
||||
print("=== MVP Funkciók Tesztelése ===")
|
||||
|
||||
# 1. Bejelentkezés
|
||||
print("\n1. Bejelentkezés...")
|
||||
# Próbáljuk a korábban regisztrált tesztfelhasználót
|
||||
token = login("test@profibot.hu", "test123")
|
||||
if not token:
|
||||
print("First login attempt failed, trying testuser@example.com")
|
||||
token = login("testuser@example.com", "TestPass123!")
|
||||
|
||||
if not token:
|
||||
print("ERROR: Could not obtain access token. Exiting.")
|
||||
sys.exit(1)
|
||||
|
||||
# Frissítjük a headers-t a token-nel
|
||||
HEADERS["Authorization"] = f"Bearer {token}"
|
||||
|
||||
# 2. Jármű rögzítése
|
||||
print("\n2. Jármű rögzítése...")
|
||||
asset_id = test_vehicle_creation(token)
|
||||
|
||||
if asset_id:
|
||||
# 3. Jármű költség rögzítése
|
||||
print("\n3. Jármű költség rögzítése...")
|
||||
test_expense_creation(token, asset_id)
|
||||
else:
|
||||
print("Skipping expense creation - no asset_id")
|
||||
|
||||
# 4. Szervizpont keresés
|
||||
print("\n4. Szervizpont keresés...")
|
||||
test_service_search(token)
|
||||
|
||||
# 5. Gamification státusz
|
||||
print("\n5. Gamification státusz lekérése...")
|
||||
test_gamification_stats(token)
|
||||
|
||||
# 6. Wallet egyenleg
|
||||
print("\n6. Wallet egyenleg lekérése...")
|
||||
test_wallet_balance(token)
|
||||
|
||||
print("\n=== Tesztelés befejezve ===")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
91
tests/archive/test_mvp.sh.old
Executable file
91
tests/archive/test_mvp.sh.old
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
BASE_URL="http://192.168.100.10:8000/api/v1"
|
||||
HEADERS="Content-Type: application/json"
|
||||
|
||||
echo "=== MVP Funkciók Tesztelése ==="
|
||||
|
||||
# 1. Bejelentkezés
|
||||
echo -e "\n1. Bejelentkezés..."
|
||||
LOGIN_RESP=$(curl -s -X POST "$BASE_URL/auth/login" \
|
||||
-H "$HEADERS" \
|
||||
-d '{"username": "test@profibot.hu", "password": "test123"}')
|
||||
|
||||
echo "Login response: $LOGIN_RESP"
|
||||
|
||||
TOKEN=$(echo "$LOGIN_RESP" | grep -o '"access_token":"[^"]*"' | cut -d'"' -f4)
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "First login failed, trying testuser@example.com"
|
||||
LOGIN_RESP=$(curl -s -X POST "$BASE_URL/auth/login" \
|
||||
-H "$HEADERS" \
|
||||
-d '{"username": "testuser@example.com", "password": "TestPass123!"}')
|
||||
echo "Second login response: $LOGIN_RESP"
|
||||
TOKEN=$(echo "$LOGIN_RESP" | grep -o '"access_token":"[^"]*"' | cut -d'"' -f4)
|
||||
fi
|
||||
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "ERROR: Could not obtain access token. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Token obtained: ${TOKEN:0:20}..."
|
||||
|
||||
AUTH_HEADER="Authorization: Bearer $TOKEN"
|
||||
|
||||
# 2. Jármű rögzítése
|
||||
echo -e "\n2. Jármű rögzítése..."
|
||||
VEHICLE_RESP=$(curl -s -X POST "$BASE_URL/assets/vehicles" \
|
||||
-H "$HEADERS" \
|
||||
-H "$AUTH_HEADER" \
|
||||
-d '{
|
||||
"plate_number": "ABC-123",
|
||||
"vin": "1HGCM82633A123456",
|
||||
"make": "Honda",
|
||||
"model": "Accord",
|
||||
"year": 2020
|
||||
}')
|
||||
|
||||
echo "Vehicle creation response: $VEHICLE_RESP"
|
||||
|
||||
ASSET_ID=$(echo "$VEHICLE_RESP" | grep -o '"asset_id":"[^"]*"' | cut -d'"' -f4)
|
||||
if [ -n "$ASSET_ID" ]; then
|
||||
echo "Vehicle created with asset_id: $ASSET_ID"
|
||||
|
||||
# 3. Jármű költség rögzítése
|
||||
echo -e "\n3. Jármű költség rögzítése..."
|
||||
EXPENSE_RESP=$(curl -s -X POST "$BASE_URL/expenses/" \
|
||||
-H "$HEADERS" \
|
||||
-H "$AUTH_HEADER" \
|
||||
-d "{
|
||||
\"asset_id\": \"$ASSET_ID\",
|
||||
\"cost_type\": \"fuel\",
|
||||
\"amount\": 15000,
|
||||
\"currency\": \"HUF\",
|
||||
\"odometer\": 50000,
|
||||
\"description\": \"Tankolás\"
|
||||
}")
|
||||
echo "Expense creation response: $EXPENSE_RESP"
|
||||
else
|
||||
echo "Skipping expense creation - no asset_id"
|
||||
fi
|
||||
|
||||
# 4. Szervizpont keresés
|
||||
echo -e "\n4. Szervizpont keresés..."
|
||||
SERVICE_RESP=$(curl -s -X GET "$BASE_URL/services/search?query=autószerviz" \
|
||||
-H "$AUTH_HEADER")
|
||||
echo "Service search response: $SERVICE_RESP"
|
||||
|
||||
# 5. Gamification státusz
|
||||
echo -e "\n5. Gamification státusz lekérése..."
|
||||
GAMIFICATION_RESP=$(curl -s -X GET "$BASE_URL/gamification/my-stats" \
|
||||
-H "$AUTH_HEADER")
|
||||
echo "Gamification stats response: $GAMIFICATION_RESP"
|
||||
|
||||
# 6. Wallet egyenleg
|
||||
echo -e "\n6. Wallet egyenleg lekérése..."
|
||||
USER_RESP=$(curl -s -X GET "$BASE_URL/users/me" \
|
||||
-H "$AUTH_HEADER")
|
||||
echo "User wallet balance response: $USER_RESP"
|
||||
|
||||
echo -e "\n=== Tesztelés befejezve ==="
|
||||
137
tests/archive/test_onboard_fix.py.old
Normal file
137
tests/archive/test_onboard_fix.py.old
Normal file
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for verifying the POST /api/v1/organizations/onboard fix.
|
||||
Creates a new organization with unique tax number and verifies that
|
||||
a default main branch is automatically created.
|
||||
"""
|
||||
import asyncio
|
||||
import aiohttp
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
API_BASE = "http://localhost:8000/api/v1"
|
||||
TEST_USER_EMAIL = "kincses@gmail.com"
|
||||
TEST_USER_PASSWORD = "MiskociA74" # From .env PGADMIN password (likely same)
|
||||
|
||||
async def get_auth_token(session):
|
||||
"""Authenticate and get JWT token."""
|
||||
login_url = f"{API_BASE}/auth/login"
|
||||
login_data = {
|
||||
"username": TEST_USER_EMAIL,
|
||||
"password": TEST_USER_PASSWORD
|
||||
}
|
||||
try:
|
||||
async with session.post(login_url, json=login_data) as resp:
|
||||
if resp.status != 200:
|
||||
print(f"Login failed: {resp.status}")
|
||||
text = await resp.text()
|
||||
print(f"Response: {text}")
|
||||
return None
|
||||
data = await resp.json()
|
||||
return data.get("access_token")
|
||||
except Exception as e:
|
||||
print(f"Login error: {e}")
|
||||
return None
|
||||
|
||||
async def create_test_organization(session, token):
|
||||
"""Create a new organization with unique tax number."""
|
||||
onboard_url = f"{API_BASE}/organizations/onboard"
|
||||
# Generate unique tax number: 98765432-1-11 + timestamp to avoid conflicts
|
||||
timestamp = datetime.now().strftime("%H%M%S")
|
||||
tax_number = f"98765432-1-{timestamp[-2:]}" # Use last 2 digits of timestamp
|
||||
|
||||
org_data = {
|
||||
"full_name": "Auto-Fixer Pro Kft.",
|
||||
"name": "AutoFixerPro",
|
||||
"display_name": "Auto-Fixer Pro",
|
||||
"tax_number": tax_number,
|
||||
"reg_number": "01-09-123456",
|
||||
"country_code": "HU",
|
||||
"address_zip": "1234",
|
||||
"address_city": "Budapest",
|
||||
"address_street_name": "Teszt utca",
|
||||
"address_street_type": "utca",
|
||||
"address_house_number": "42",
|
||||
"address_hrsz": ""
|
||||
}
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
async with session.post(onboard_url, json=org_data, headers=headers) as resp:
|
||||
if resp.status != 201:
|
||||
print(f"Organization creation failed: {resp.status}")
|
||||
text = await resp.text()
|
||||
print(f"Response: {text}")
|
||||
return None
|
||||
data = await resp.json()
|
||||
print(f"Organization created successfully: {data}")
|
||||
return data.get("organization_id")
|
||||
|
||||
async def get_my_organizations(session, token):
|
||||
"""Get list of organizations for current user."""
|
||||
url = f"{API_BASE}/organizations/my"
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
async with session.get(url, headers=headers) as resp:
|
||||
if resp.status != 200:
|
||||
print(f"Failed to get organizations: {resp.status}")
|
||||
return []
|
||||
return await resp.json()
|
||||
|
||||
async def check_branches_via_sql(org_id):
|
||||
"""Check if branch exists via direct SQL query in container."""
|
||||
import subprocess
|
||||
# Use docker exec to query PostgreSQL
|
||||
cmd = [
|
||||
"docker", "exec", "shared-postgres",
|
||||
"psql", "-U", "kincses", "-d", "service_finder", "-c",
|
||||
f"SELECT id, name, is_main FROM fleet.branches WHERE organization_id = {org_id};"
|
||||
]
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
print("SQL Query Result:")
|
||||
print(result.stdout)
|
||||
if result.returncode != 0:
|
||||
print(f"SQL Error: {result.stderr}")
|
||||
return "Központi Telephely" in result.stdout
|
||||
except Exception as e:
|
||||
print(f"SQL check error: {e}")
|
||||
return False
|
||||
|
||||
async def main():
|
||||
print("=== Testing Organization Onboard Fix ===")
|
||||
print("1. Authenticating...")
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
token = await get_auth_token(session)
|
||||
if not token:
|
||||
print("Authentication failed. Exiting.")
|
||||
sys.exit(1)
|
||||
print(f"Token obtained: {token[:20]}...")
|
||||
|
||||
print("\n2. Creating test organization...")
|
||||
org_id = await create_test_organization(session, token)
|
||||
if not org_id:
|
||||
print("Organization creation failed. Exiting.")
|
||||
sys.exit(1)
|
||||
print(f"Organization ID: {org_id}")
|
||||
|
||||
print("\n3. Fetching user's organizations...")
|
||||
orgs = await get_my_organizations(session, token)
|
||||
print(f"Total organizations for user: {len(orgs)}")
|
||||
for org in orgs:
|
||||
if org.get("organization_id") == org_id:
|
||||
print(f" Found created org: {org}")
|
||||
break
|
||||
|
||||
print("\n4. Checking for default branch via SQL...")
|
||||
branch_exists = await check_branches_via_sql(org_id)
|
||||
if branch_exists:
|
||||
print("✅ SUCCESS: Default main branch 'Központi Telephely' was automatically created!")
|
||||
else:
|
||||
print("❌ FAIL: No default branch found.")
|
||||
sys.exit(1)
|
||||
|
||||
print("\n=== Test completed successfully ===")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
138
tests/archive/test_onboard_fix_v2.py.old
Normal file
138
tests/archive/test_onboard_fix_v2.py.old
Normal file
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for verifying the POST /api/v1/organizations/onboard fix.
|
||||
Creates a new organization with unique tax number and verifies that
|
||||
a default main branch is automatically created.
|
||||
"""
|
||||
import asyncio
|
||||
import aiohttp
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
API_BASE = "http://localhost:8000/api/v1"
|
||||
TEST_USER_EMAIL = "kincses@gmail.com"
|
||||
TEST_USER_PASSWORD = "MiskociA74" # From .env PGADMIN password (likely same)
|
||||
|
||||
async def get_auth_token(session):
|
||||
"""Authenticate and get JWT token using form data."""
|
||||
login_url = f"{API_BASE}/auth/login"
|
||||
# Use form data as required by OAuth2PasswordRequestForm
|
||||
form_data = aiohttp.FormData()
|
||||
form_data.add_field('username', TEST_USER_EMAIL)
|
||||
form_data.add_field('password', TEST_USER_PASSWORD)
|
||||
|
||||
try:
|
||||
async with session.post(login_url, data=form_data) as resp:
|
||||
if resp.status != 200:
|
||||
print(f"Login failed: {resp.status}")
|
||||
text = await resp.text()
|
||||
print(f"Response: {text}")
|
||||
return None
|
||||
data = await resp.json()
|
||||
return data.get("access_token")
|
||||
except Exception as e:
|
||||
print(f"Login error: {e}")
|
||||
return None
|
||||
|
||||
async def create_test_organization(session, token):
|
||||
"""Create a new organization with unique tax number."""
|
||||
onboard_url = f"{API_BASE}/organizations/onboard"
|
||||
# Generate unique tax number: 98765432-1-11 + timestamp to avoid conflicts
|
||||
timestamp = datetime.now().strftime("%H%M%S")
|
||||
tax_number = f"98765432-1-{timestamp[-2:]}" # Use last 2 digits of timestamp
|
||||
|
||||
org_data = {
|
||||
"full_name": "Auto-Fixer Pro Kft.",
|
||||
"name": "AutoFixerPro",
|
||||
"display_name": "Auto-Fixer Pro",
|
||||
"tax_number": tax_number,
|
||||
"reg_number": "01-09-123456",
|
||||
"country_code": "HU",
|
||||
"address_zip": "1234",
|
||||
"address_city": "Budapest",
|
||||
"address_street_name": "Teszt utca",
|
||||
"address_street_type": "utca",
|
||||
"address_house_number": "42",
|
||||
"address_hrsz": ""
|
||||
}
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
async with session.post(onboard_url, json=org_data, headers=headers) as resp:
|
||||
if resp.status != 201:
|
||||
print(f"Organization creation failed: {resp.status}")
|
||||
text = await resp.text()
|
||||
print(f"Response: {text}")
|
||||
return None
|
||||
data = await resp.json()
|
||||
print(f"Organization created successfully: {data}")
|
||||
return data.get("organization_id")
|
||||
|
||||
async def get_my_organizations(session, token):
|
||||
"""Get list of organizations for current user."""
|
||||
url = f"{API_BASE}/organizations/my"
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
async with session.get(url, headers=headers) as resp:
|
||||
if resp.status != 200:
|
||||
print(f"Failed to get organizations: {resp.status}")
|
||||
return []
|
||||
return await resp.json()
|
||||
|
||||
async def check_branches_via_sql(org_id):
|
||||
"""Check if branch exists via direct SQL query in container."""
|
||||
import subprocess
|
||||
# Use docker exec to query PostgreSQL
|
||||
cmd = [
|
||||
"docker", "exec", "shared-postgres",
|
||||
"psql", "-U", "kincses", "-d", "service_finder", "-c",
|
||||
f"SELECT id, name, is_main FROM fleet.branches WHERE organization_id = {org_id};"
|
||||
]
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
print("SQL Query Result:")
|
||||
print(result.stdout)
|
||||
if result.returncode != 0:
|
||||
print(f"SQL Error: {result.stderr}")
|
||||
return "Központi Telephely" in result.stdout
|
||||
except Exception as e:
|
||||
print(f"SQL check error: {e}")
|
||||
return False
|
||||
|
||||
async def main():
|
||||
print("=== Testing Organization Onboard Fix ===")
|
||||
print("1. Authenticating...")
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
token = await get_auth_token(session)
|
||||
if not token:
|
||||
print("Authentication failed. Exiting.")
|
||||
sys.exit(1)
|
||||
print(f"Token obtained: {token[:20]}...")
|
||||
|
||||
print("\n2. Creating test organization...")
|
||||
org_id = await create_test_organization(session, token)
|
||||
if not org_id:
|
||||
print("Organization creation failed. Exiting.")
|
||||
sys.exit(1)
|
||||
print(f"Organization ID: {org_id}")
|
||||
|
||||
print("\n3. Fetching user's organizations...")
|
||||
orgs = await get_my_organizations(session, token)
|
||||
print(f"Total organizations for user: {len(orgs)}")
|
||||
for org in orgs:
|
||||
if org.get("organization_id") == org_id:
|
||||
print(f" Found created org: {org}")
|
||||
break
|
||||
|
||||
print("\n4. Checking for default branch via SQL...")
|
||||
branch_exists = await check_branches_via_sql(org_id)
|
||||
if branch_exists:
|
||||
print("✅ SUCCESS: Default main branch 'Központi Telephely' was automatically created!")
|
||||
else:
|
||||
print("❌ FAIL: No default branch found.")
|
||||
sys.exit(1)
|
||||
|
||||
print("\n=== Test completed successfully ===")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
123
tests/archive/test_onboard_integration.py.old
Normal file
123
tests/archive/test_onboard_integration.py.old
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Integration test for the organization onboard fix.
|
||||
Uses TestClient to call the endpoint and checks if a branch is created.
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, '/app/backend')
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from app.main import app
|
||||
from app.db.session import get_db
|
||||
from app.models.marketplace.organization import Organization, Branch
|
||||
from app.models.identity import User
|
||||
from app.core.security import create_access_token
|
||||
import uuid
|
||||
|
||||
# Override get_db to use test database
|
||||
TEST_DATABASE_URL = os.getenv("DATABASE_URL", "postgresql+asyncpg://service_finder_app:AppSafePass_2026@postgres-db:5432/service_finder")
|
||||
|
||||
engine = create_async_engine(TEST_DATABASE_URL)
|
||||
AsyncTestingSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
async def override_get_db():
|
||||
async with AsyncTestingSessionLocal() as session:
|
||||
yield session
|
||||
|
||||
app.dependency_overrides[get_db] = override_get_db
|
||||
|
||||
async def test_onboard_creates_branch():
|
||||
"""Test that onboard endpoint creates a default main branch."""
|
||||
client = TestClient(app)
|
||||
|
||||
# First, we need an authenticated user. Let's get an existing user from the database.
|
||||
async with AsyncTestingSessionLocal() as db:
|
||||
# Find any active user
|
||||
from sqlalchemy import select
|
||||
stmt = select(User).where(User.is_active == True).limit(1)
|
||||
result = await db.execute(stmt)
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
print("No active user found in database. Skipping test.")
|
||||
return False
|
||||
|
||||
# Create a JWT token for this user
|
||||
token = create_access_token(data={"sub": user.email})
|
||||
|
||||
# Generate unique tax number
|
||||
import datetime
|
||||
timestamp = datetime.datetime.now().strftime("%H%M%S")
|
||||
tax_number = f"98765432-1-{timestamp[-2:]}"
|
||||
|
||||
# Call onboard endpoint
|
||||
org_data = {
|
||||
"full_name": "Auto-Fixer Pro Kft.",
|
||||
"name": "AutoFixerPro",
|
||||
"display_name": "Auto-Fixer Pro",
|
||||
"tax_number": tax_number,
|
||||
"reg_number": "01-09-123456",
|
||||
"country_code": "HU",
|
||||
"address_zip": "1234",
|
||||
"address_city": "Budapest",
|
||||
"address_street_name": "Teszt utca",
|
||||
"address_street_type": "utca",
|
||||
"address_house_number": "42",
|
||||
"address_hrsz": ""
|
||||
}
|
||||
|
||||
response = client.post(
|
||||
"/api/v1/organizations/onboard",
|
||||
json=org_data,
|
||||
headers={"Authorization": f"Bearer {token}"}
|
||||
)
|
||||
|
||||
print(f"Response status: {response.status_code}")
|
||||
if response.status_code != 201:
|
||||
print(f"Error: {response.text}")
|
||||
return False
|
||||
|
||||
org_response = response.json()
|
||||
org_id = org_response.get("organization_id")
|
||||
print(f"Organization created with ID: {org_id}")
|
||||
|
||||
# Now check if a branch was created
|
||||
async with AsyncTestingSessionLocal() as db:
|
||||
stmt = select(Branch).where(
|
||||
Branch.organization_id == org_id,
|
||||
Branch.is_main == True
|
||||
)
|
||||
result = await db.execute(stmt)
|
||||
branch = result.scalar_one_or_none()
|
||||
|
||||
if branch:
|
||||
print(f"✅ SUCCESS: Default branch created: {branch.name} (ID: {branch.id})")
|
||||
# Cleanup: delete the test organization and branch
|
||||
# (optional, but good practice)
|
||||
await db.delete(branch)
|
||||
org_stmt = select(Organization).where(Organization.id == org_id)
|
||||
org_result = await db.execute(org_stmt)
|
||||
org = org_result.scalar_one_or_none()
|
||||
if org:
|
||||
await db.delete(org)
|
||||
await db.commit()
|
||||
return True
|
||||
else:
|
||||
print("❌ FAIL: No default branch found.")
|
||||
return False
|
||||
|
||||
async def main():
|
||||
print("=== Running Organization Onboard Integration Test ===")
|
||||
success = await test_onboard_creates_branch()
|
||||
if success:
|
||||
print("\n✅ Test PASSED: Branch creation fix works!")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("\n❌ Test FAILED: Branch not created.")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
65
tests/archive/test_token_debug.py.old
Normal file
65
tests/archive/test_token_debug.py.old
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Debug script to check the PATCH endpoint response
|
||||
"""
|
||||
import asyncio
|
||||
import httpx
|
||||
import json
|
||||
|
||||
async def test():
|
||||
base_url = "http://sf_api:8000"
|
||||
|
||||
print("1. Logging in...")
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
# Login
|
||||
login_data = {
|
||||
"username": "tester_pro@profibot.hu",
|
||||
"password": "Password123!"
|
||||
}
|
||||
|
||||
resp = await client.post(
|
||||
f"{base_url}/api/v1/auth/login",
|
||||
data=login_data
|
||||
)
|
||||
print(f"Login status: {resp.status_code}")
|
||||
if resp.status_code != 200:
|
||||
print(f"Login response: {resp.text}")
|
||||
return
|
||||
|
||||
login_result = resp.json()
|
||||
initial_token = login_result["access_token"]
|
||||
print(f"Initial token: {initial_token[:50]}...")
|
||||
|
||||
# Test PATCH
|
||||
print("\n2. Testing PATCH /users/me/active-organization...")
|
||||
headers = {"Authorization": f"Bearer {initial_token}", "Content-Type": "application/json"}
|
||||
patch_data = {"organization_id": None}
|
||||
|
||||
resp = await client.patch(
|
||||
f"{base_url}/api/v1/users/me/active-organization",
|
||||
json=patch_data,
|
||||
headers=headers
|
||||
)
|
||||
|
||||
print(f"PATCH status: {resp.status_code}")
|
||||
print(f"PATCH headers: {dict(resp.headers)}")
|
||||
print(f"PATCH response text: {resp.text}")
|
||||
|
||||
if resp.status_code == 200:
|
||||
try:
|
||||
result = resp.json()
|
||||
print(f"\nParsed JSON response:")
|
||||
print(json.dumps(result, indent=2))
|
||||
|
||||
if "access_token" in result:
|
||||
print(f"\n✓ access_token found in response")
|
||||
print(f"New token: {result['access_token'][:50]}...")
|
||||
else:
|
||||
print(f"\n⚠️ access_token NOT found in response")
|
||||
print(f"Available keys: {list(result.keys())}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"JSON parse error: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test())
|
||||
131
tests/archive/test_token_refresh.py.old
Normal file
131
tests/archive/test_token_refresh.py.old
Normal file
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to verify the token refresh functionality in PATCH /api/v1/users/me/active-organization
|
||||
"""
|
||||
import asyncio
|
||||
import aiohttp
|
||||
import json
|
||||
|
||||
async def test_token_refresh():
|
||||
base_url = "http://sf_api:8000"
|
||||
|
||||
# 1. Login to get initial token
|
||||
print("1. Logging in as tester_pro@profibot.hu...")
|
||||
async with aiohttp.ClientSession() as session:
|
||||
# Login
|
||||
login_data = {
|
||||
"username": "tester_pro@profibot.hu",
|
||||
"password": "TestPassword123!"
|
||||
}
|
||||
|
||||
async with session.post(
|
||||
f"{base_url}/api/v1/auth/login",
|
||||
data=login_data
|
||||
) as resp:
|
||||
if resp.status != 200:
|
||||
print(f"Login failed: {resp.status}")
|
||||
text = await resp.text()
|
||||
print(f"Response: {text}")
|
||||
return
|
||||
|
||||
login_result = await resp.json()
|
||||
initial_token = login_result["access_token"]
|
||||
print(f"✓ Initial token obtained: {initial_token[:50]}...")
|
||||
|
||||
# 2. Test switching to personal mode (organization_id = null)
|
||||
print("\n2. Switching to personal mode (organization_id = null)...")
|
||||
headers = {"Authorization": f"Bearer {initial_token}", "Content-Type": "application/json"}
|
||||
patch_data = {"organization_id": None}
|
||||
|
||||
async with session.patch(
|
||||
f"{base_url}/api/v1/users/me/active-organization",
|
||||
json=patch_data,
|
||||
headers=headers
|
||||
) as resp:
|
||||
if resp.status != 200:
|
||||
print(f"PATCH failed: {resp.status}")
|
||||
text = await resp.text()
|
||||
print(f"Response: {text}")
|
||||
return
|
||||
|
||||
patch_result = await resp.json()
|
||||
new_token = patch_result["access_token"]
|
||||
user_data = patch_result["user"]
|
||||
print(f"✓ New token received: {new_token[:50]}...")
|
||||
print(f"✓ User scope_id: {user_data.get('scope_id')}")
|
||||
print(f"✓ Token type: {patch_result.get('token_type')}")
|
||||
|
||||
# Verify tokens are different
|
||||
if new_token != initial_token:
|
||||
print("✓ Token refreshed successfully (tokens are different)")
|
||||
else:
|
||||
print("⚠️ Token not refreshed (tokens are the same)")
|
||||
|
||||
# 3. Test switching to Alpha organization (ID 26)
|
||||
print("\n3. Switching to Alpha organization (ID 26)...")
|
||||
headers = {"Authorization": f"Bearer {new_token}", "Content-Type": "application/json"}
|
||||
patch_data = {"organization_id": "26"}
|
||||
|
||||
async with session.patch(
|
||||
f"{base_url}/api/v1/users/me/active-organization",
|
||||
json=patch_data,
|
||||
headers=headers
|
||||
) as resp:
|
||||
if resp.status != 200:
|
||||
print(f"PATCH failed: {resp.status}")
|
||||
text = await resp.text()
|
||||
print(f"Response: {text}")
|
||||
return
|
||||
|
||||
patch_result = await resp.json()
|
||||
alpha_token = patch_result["access_token"]
|
||||
user_data = patch_result["user"]
|
||||
print(f"✓ New token for Alpha: {alpha_token[:50]}...")
|
||||
print(f"✓ User scope_id: {user_data.get('scope_id')}")
|
||||
|
||||
if alpha_token != new_token:
|
||||
print("✓ Token refreshed again for Alpha organization")
|
||||
else:
|
||||
print("⚠️ Token not refreshed for Alpha")
|
||||
|
||||
# 4. Test switching to Beta organization (ID 27)
|
||||
print("\n4. Switching to Beta organization (ID 27)...")
|
||||
headers = {"Authorization": f"Bearer {alpha_token}", "Content-Type": "application/json"}
|
||||
patch_data = {"organization_id": "27"}
|
||||
|
||||
async with session.patch(
|
||||
f"{base_url}/api/v1/users/me/active-organization",
|
||||
json=patch_data,
|
||||
headers=headers
|
||||
) as resp:
|
||||
if resp.status != 200:
|
||||
print(f"PATCH failed: {resp.status}")
|
||||
text = await resp.text()
|
||||
print(f"Response: {text}")
|
||||
return
|
||||
|
||||
patch_result = await resp.json()
|
||||
beta_token = patch_result["access_token"]
|
||||
user_data = patch_result["user"]
|
||||
print(f"✓ New token for Beta: {beta_token[:50]}...")
|
||||
print(f"✓ User scope_id: {user_data.get('scope_id')}")
|
||||
|
||||
if beta_token != alpha_token:
|
||||
print("✓ Token refreshed again for Beta organization")
|
||||
else:
|
||||
print("⚠️ Token not refreshed for Beta")
|
||||
|
||||
# 5. Verify all tokens are different
|
||||
print("\n5. Verifying all tokens are unique...")
|
||||
tokens = [initial_token, new_token, alpha_token, beta_token]
|
||||
unique_tokens = set(tokens)
|
||||
|
||||
if len(unique_tokens) == len(tokens):
|
||||
print("✓ All tokens are unique (proper refresh on each organization switch)")
|
||||
else:
|
||||
print(f"⚠️ Only {len(unique_tokens)} unique tokens out of {len(tokens)}")
|
||||
|
||||
print("\n=== TEST COMPLETED SUCCESSFULLY ===")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_token_refresh())
|
||||
82
tests/archive/test_token_refresh_simple.py.old
Normal file
82
tests/archive/test_token_refresh_simple.py.old
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple test script to verify token refresh functionality
|
||||
"""
|
||||
import asyncio
|
||||
import httpx
|
||||
import json
|
||||
|
||||
async def test_token_refresh():
|
||||
base_url = "http://sf_api:8000"
|
||||
|
||||
print("1. Logging in as tester_pro@profibot.hu...")
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
# Login
|
||||
login_data = {
|
||||
"username": "tester_pro@profibot.hu",
|
||||
"password": "Password123!"
|
||||
}
|
||||
|
||||
try:
|
||||
resp = await client.post(
|
||||
f"{base_url}/api/v1/auth/login",
|
||||
data=login_data
|
||||
)
|
||||
resp.raise_for_status()
|
||||
login_result = resp.json()
|
||||
initial_token = login_result["access_token"]
|
||||
print(f"✓ Initial token obtained: {initial_token[:50]}...")
|
||||
except Exception as e:
|
||||
print(f"Login failed: {e}")
|
||||
return
|
||||
|
||||
# Test switching to personal mode
|
||||
print("\n2. Switching to personal mode (organization_id = null)...")
|
||||
headers = {"Authorization": f"Bearer {initial_token}", "Content-Type": "application/json"}
|
||||
patch_data = {"organization_id": None}
|
||||
|
||||
try:
|
||||
resp = await client.patch(
|
||||
f"{base_url}/api/v1/users/me/active-organization",
|
||||
json=patch_data,
|
||||
headers=headers
|
||||
)
|
||||
resp.raise_for_status()
|
||||
patch_result = resp.json()
|
||||
new_token = patch_result["access_token"]
|
||||
user_data = patch_result["user"]
|
||||
print(f"✓ New token received: {new_token[:50]}...")
|
||||
print(f"✓ User scope_id: {user_data.get('scope_id')}")
|
||||
print(f"✓ Token type: {patch_result.get('token_type')}")
|
||||
|
||||
if new_token != initial_token:
|
||||
print("✓ Token refreshed successfully (tokens are different)")
|
||||
else:
|
||||
print("⚠️ Token not refreshed (tokens are the same)")
|
||||
|
||||
# Decode token to verify scope_id in payload
|
||||
import jwt
|
||||
from app.core.config import settings
|
||||
try:
|
||||
payload = jwt.decode(new_token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
|
||||
print(f"✓ Token payload scope_id: {payload.get('scope_id')}")
|
||||
print(f"✓ Token payload scope_level: {payload.get('scope_level')}")
|
||||
except:
|
||||
print("⚠️ Could not decode token")
|
||||
|
||||
except Exception as e:
|
||||
print(f"PATCH failed: {e}")
|
||||
if hasattr(e, 'response'):
|
||||
try:
|
||||
print(f"Response status: {e.response.status_code}")
|
||||
print(f"Response text: {e.response.text}")
|
||||
except:
|
||||
pass
|
||||
return
|
||||
|
||||
print("\n=== TEST COMPLETED SUCCESSFULLY ===")
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = asyncio.run(test_token_refresh())
|
||||
exit(0 if success else 1)
|
||||
140
tests/archive/test_user55_api.py.old
Normal file
140
tests/archive/test_user55_api.py.old
Normal file
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
API teszt script User 55 számára - hivatalos API végpontok használatával
|
||||
"""
|
||||
import sys
|
||||
import asyncio
|
||||
import httpx
|
||||
import json
|
||||
|
||||
sys.path.append('/app/backend')
|
||||
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from sqlalchemy import select
|
||||
from app.models.identity import User
|
||||
from app.core.security import create_tokens
|
||||
|
||||
async def get_auth_token():
|
||||
"""Hitelesítési token lekérése User 55 számára"""
|
||||
async with AsyncSessionLocal() as db:
|
||||
result = await db.execute(select(User).where(User.id == 55))
|
||||
user = result.scalar_one_or_none()
|
||||
if user:
|
||||
access_token, _ = create_tokens(data={'sub': str(user.id)})
|
||||
return access_token
|
||||
else:
|
||||
raise Exception("User 55 nem található")
|
||||
|
||||
async def test_api_endpoints():
|
||||
"""API végpontok tesztelése"""
|
||||
# Token lekérése
|
||||
token = await get_auth_token()
|
||||
print("✅ Hitelesítési token megkapva User 55 számára")
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient(base_url="http://localhost:8000", timeout=30.0) as client:
|
||||
print("\n=== API TESZTEK ===")
|
||||
|
||||
# 1. Szervezetek listázása
|
||||
print("\n1. GET /api/v1/organizations/my - Szervezetek listázása")
|
||||
try:
|
||||
response = await client.get("/api/v1/organizations/my", headers=headers)
|
||||
print(f" Status: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
orgs = response.json()
|
||||
print(f" Talált szervezetek: {len(orgs)} db")
|
||||
|
||||
for i, org in enumerate(orgs, 1):
|
||||
print(f" {i}. {org.get('full_name')} (ID: {org.get('organization_id')})")
|
||||
print(f" Típus: {org.get('name')}, Adószám: {org.get('tax_number')}")
|
||||
print(f" Státusz: {org.get('status')}, Aktív: {org.get('is_active')}")
|
||||
else:
|
||||
print(f" Hiba: {response.text}")
|
||||
except Exception as e:
|
||||
print(f" Hiba a kérés során: {e}")
|
||||
|
||||
# 2. Gamification ellenőrzés (ha van API)
|
||||
print("\n2. Gamification státusz (adatbázis ellenőrzés)")
|
||||
async with AsyncSessionLocal() as db:
|
||||
from sqlalchemy import text
|
||||
result = await db.execute(text('''
|
||||
SELECT total_xp, current_level
|
||||
FROM gamification.user_stats
|
||||
WHERE user_id = 55
|
||||
'''))
|
||||
stats = result.fetchone()
|
||||
if stats:
|
||||
stats_dict = dict(stats._mapping)
|
||||
print(f" Összes XP: {stats_dict['total_xp']}")
|
||||
print(f" Jelenlegi szint: {stats_dict['current_level']}")
|
||||
|
||||
# Points ledger ellenőrzés
|
||||
result = await db.execute(text('''
|
||||
SELECT reason, points, created_at::date as date
|
||||
FROM gamification.points_ledger
|
||||
WHERE user_id = 55
|
||||
ORDER BY created_at DESC
|
||||
'''))
|
||||
ledger = result.fetchall()
|
||||
print(f" Ponttörténet: {len(ledger)} bejegyzés")
|
||||
for entry in ledger:
|
||||
entry_dict = dict(entry._mapping)
|
||||
print(f" - {entry_dict['reason']}: {entry_dict['points']} pont ({entry_dict['date']})")
|
||||
|
||||
# 3. User scope ellenőrzés
|
||||
print("\n3. User scope információ")
|
||||
async with AsyncSessionLocal() as db:
|
||||
result = await db.execute(text('''
|
||||
SELECT scope_level, scope_id
|
||||
FROM identity.users
|
||||
WHERE id = 55
|
||||
'''))
|
||||
user_scope = result.fetchone()
|
||||
if user_scope:
|
||||
scope_dict = dict(user_scope._mapping)
|
||||
print(f" Scope level: {scope_dict['scope_level']}")
|
||||
print(f" Scope ID: {scope_dict['scope_id']}")
|
||||
|
||||
# Scope organization ellenőrzés
|
||||
if scope_dict['scope_id']:
|
||||
result = await db.execute(text(f'''
|
||||
SELECT full_name, org_type
|
||||
FROM fleet.organizations
|
||||
WHERE id = {scope_dict['scope_id']}
|
||||
'''))
|
||||
scope_org = result.fetchone()
|
||||
if scope_org:
|
||||
scope_org_dict = dict(scope_org._mapping)
|
||||
print(f" Scope szervezet: {scope_org_dict['full_name']} ({scope_org_dict['org_type']})")
|
||||
|
||||
# 4. Telephelyek ellenőrzés
|
||||
print("\n4. Telephelyek (adatbázis)")
|
||||
async with AsyncSessionLocal() as db:
|
||||
result = await db.execute(text('''
|
||||
SELECT b.name, b.is_main, o.full_name as org_name
|
||||
FROM fleet.branches b
|
||||
JOIN fleet.organizations o ON b.organization_id = o.id
|
||||
WHERE b.organization_id IN (
|
||||
SELECT organization_id FROM fleet.organization_members WHERE user_id = 55
|
||||
)
|
||||
ORDER BY b.is_main DESC
|
||||
'''))
|
||||
branches = result.fetchall()
|
||||
print(f" Talált telephelyek: {len(branches)} db")
|
||||
for branch in branches:
|
||||
branch_dict = dict(branch._mapping)
|
||||
main_str = "FŐTELEPHELY" if branch_dict['is_main'] else "melléktelephely"
|
||||
print(f" - {branch_dict['org_name']}: {branch_dict['name']} ({main_str})")
|
||||
|
||||
async def main():
|
||||
print("=== USER 55 API TESZTELÉSE ===")
|
||||
print("Felhasználó: test_fallback@profibot.hu (ID: 55)")
|
||||
await test_api_endpoints()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
174
tests/archive/verify_org_structure.py.old
Normal file
174
tests/archive/verify_org_structure.py.old
Normal file
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Verify organizational structure after KYC completion for User 55
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import text
|
||||
from app.core.config import settings
|
||||
|
||||
async def verify_org_structure():
|
||||
# Create database connection
|
||||
engine = create_async_engine(settings.DATABASE_URL, echo=False)
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
async with async_session() as db:
|
||||
print("🔍 Verifying organizational structure for User 55")
|
||||
print("=" * 60)
|
||||
|
||||
# 1. User Link: Confirm User.person_id is correctly pointing to Person 56
|
||||
print("\n1. User Link (User.person_id -> Person 56):")
|
||||
user_query = text("""
|
||||
SELECT id, email, person_id, is_active, scope_id
|
||||
FROM identity.users
|
||||
WHERE id = 55
|
||||
""")
|
||||
user_result = await db.execute(user_query)
|
||||
user = user_result.fetchone()
|
||||
|
||||
if user:
|
||||
print(f" ✅ User 55 found:")
|
||||
print(f" - ID: {user.id}")
|
||||
print(f" - Email: {user.email}")
|
||||
print(f" - Person ID: {user.person_id} (expected: 56)")
|
||||
print(f" - Is Active: {user.is_active}")
|
||||
print(f" - Scope ID: {user.scope_id}")
|
||||
|
||||
if user.person_id == 56:
|
||||
print(" ✅ Person ID correctly points to Person 56")
|
||||
else:
|
||||
print(f" ❌ Person ID mismatch: expected 56, got {user.person_id}")
|
||||
else:
|
||||
print(" ❌ User 55 not found!")
|
||||
|
||||
# 2. Organization: Confirm a record in fleet.organizations was created
|
||||
print("\n2. Organization (fleet.organizations):")
|
||||
org_query = text("""
|
||||
SELECT id, full_name, name, org_type, owner_id, is_active, status
|
||||
FROM fleet.organizations
|
||||
WHERE owner_id = 55 AND org_type = 'individual'
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 1
|
||||
""")
|
||||
org_result = await db.execute(org_query)
|
||||
organization = org_result.fetchone()
|
||||
|
||||
if organization:
|
||||
print(f" ✅ Organization found:")
|
||||
print(f" - ID: {organization.id}")
|
||||
print(f" - Full Name: {organization.full_name}")
|
||||
print(f" - Name: {organization.name}")
|
||||
print(f" - Type: {organization.org_type}")
|
||||
print(f" - Owner ID: {organization.owner_id}")
|
||||
print(f" - Is Active: {organization.is_active}")
|
||||
print(f" - Status: {organization.status}")
|
||||
|
||||
# Check if scope_id matches organization id
|
||||
if user and str(organization.id) == user.scope_id:
|
||||
print(f" ✅ User scope_id ({user.scope_id}) matches organization ID")
|
||||
else:
|
||||
print(f" ⚠️ User scope_id ({user.scope_id if user else 'N/A'}) doesn't match organization ID ({organization.id})")
|
||||
else:
|
||||
print(" ❌ No organization found for User 55!")
|
||||
|
||||
# 3. Branch: Confirm a record in fleet.branches exists
|
||||
print("\n3. Branch (fleet.branches):")
|
||||
if organization:
|
||||
branch_query = text("""
|
||||
SELECT id, organization_id, name, is_main, address_id
|
||||
FROM fleet.branches
|
||||
WHERE organization_id = :org_id AND name = 'Home Base'
|
||||
""")
|
||||
branch_result = await db.execute(branch_query, {"org_id": organization.id})
|
||||
branch = branch_result.fetchone()
|
||||
|
||||
if branch:
|
||||
print(f" ✅ Branch 'Home Base' found:")
|
||||
print(f" - ID: {branch.id}")
|
||||
print(f" - Organization ID: {branch.organization_id}")
|
||||
print(f" - Name: {branch.name}")
|
||||
print(f" - Is Main: {branch.is_main}")
|
||||
print(f" - Address ID: {branch.address_id}")
|
||||
else:
|
||||
print(" ❌ No 'Home Base' branch found for the organization!")
|
||||
else:
|
||||
print(" ⚠️ Cannot check branches without organization")
|
||||
|
||||
# 4. Infrastructure: Confirm wallets and user_stats records
|
||||
print("\n4. Infrastructure (Wallets and User Stats):")
|
||||
|
||||
# Check wallet
|
||||
wallet_query = text("""
|
||||
SELECT id, user_id, currency, earned_credits, purchased_credits, service_coins
|
||||
FROM identity.wallets
|
||||
WHERE user_id = 55
|
||||
""")
|
||||
wallet_result = await db.execute(wallet_query)
|
||||
wallet = wallet_result.fetchone()
|
||||
|
||||
if wallet:
|
||||
print(f" ✅ Wallet found for User 55:")
|
||||
print(f" - ID: {wallet.id}")
|
||||
print(f" - User ID: {wallet.user_id}")
|
||||
print(f" - Currency: {wallet.currency}")
|
||||
print(f" - Earned Credits: {wallet.earned_credits}")
|
||||
print(f" - Purchased Credits: {wallet.purchased_credits}")
|
||||
print(f" - Service Coins: {wallet.service_coins}")
|
||||
else:
|
||||
print(" ❌ No wallet found for User 55!")
|
||||
|
||||
# Check user_stats
|
||||
stats_query = text("""
|
||||
SELECT id, user_id, total_xp, level, reputation_score
|
||||
FROM identity.user_stats
|
||||
WHERE user_id = 55
|
||||
""")
|
||||
stats_result = await db.execute(stats_query)
|
||||
user_stats = stats_result.fetchone()
|
||||
|
||||
if user_stats:
|
||||
print(f" ✅ User Stats found for User 55:")
|
||||
print(f" - ID: {user_stats.id}")
|
||||
print(f" - User ID: {user_stats.user_id}")
|
||||
print(f" - Total XP: {user_stats.total_xp}")
|
||||
print(f" - Level: {user_stats.level}")
|
||||
print(f" - Reputation Score: {user_stats.reputation_score}")
|
||||
else:
|
||||
print(" ❌ No user_stats found for User 55!")
|
||||
|
||||
# 5. Organization Member
|
||||
print("\n5. Organization Member (fleet.organization_members):")
|
||||
if organization:
|
||||
member_query = text("""
|
||||
SELECT id, organization_id, user_id, role, is_active
|
||||
FROM fleet.organization_members
|
||||
WHERE organization_id = :org_id AND user_id = 55
|
||||
""")
|
||||
member_result = await db.execute(member_query, {"org_id": organization.id})
|
||||
member = member_result.fetchone()
|
||||
|
||||
if member:
|
||||
print(f" ✅ Organization member record found:")
|
||||
print(f" - ID: {member.id}")
|
||||
print(f" - Organization ID: {member.organization_id}")
|
||||
print(f" - User ID: {member.user_id}")
|
||||
print(f" - Role: {member.role}")
|
||||
print(f" - Is Active: {member.is_active}")
|
||||
else:
|
||||
print(" ❌ No organization member record found!")
|
||||
else:
|
||||
print(" ⚠️ Cannot check organization members without organization")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Verification complete!")
|
||||
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = asyncio.run(verify_org_structure())
|
||||
sys.exit(0 if result else 1)
|
||||
Reference in New Issue
Block a user