Files
service-finder/tests/active/test_garage_selector_and_team_api.py
2026-06-17 22:07:55 +00:00

220 lines
8.4 KiB
Python

#!/usr/bin/env python3
"""
Teszt script a P0 Garage Selector Fix & Team Management API ellenőrzéséhez.
Használat:
docker compose exec sf_api python3 /app/tests/active/test_garage_selector_and_team_api.py
Ez a script:
1. Bejelentkezik admin@profibot.hu / Admin123! (Vezető Tervező, user_id=2)
2. Meghívja a GET /api/v1/organizations/my végpontot
3. Ellenőrzi, hogy a teszt cég (owner_id=2) megjelenik-e
4. Teszteli az új Team Management API végpontokat
"""
import asyncio
import json
import sys
import os
from datetime import datetime, timezone
# Add the backend directory to path
sys.path.insert(0, "/app")
import httpx
BASE_URL = os.environ.get("API_BASE_URL", "http://localhost:8000")
API_PREFIX = "/api/v1"
async def login(email: str, password: str) -> str:
"""Bejelentkezés és token lekérése."""
async with httpx.AsyncClient(base_url=BASE_URL) as client:
resp = await client.post(
f"{API_PREFIX}/auth/login",
data={"username": email, "password": password},
)
if resp.status_code != 200:
print(f"❌ Login failed: {resp.status_code} - {resp.text}")
sys.exit(1)
data = resp.json()
token = data.get("access_token") or data.get("token")
print(f"✅ Login successful (user: {email})")
return token
async def get_my_organizations(token: str) -> list:
"""GET /api/v1/organizations/my - Saját szervezetek lekérése."""
async with httpx.AsyncClient(base_url=BASE_URL) as client:
resp = await client.get(
f"{API_PREFIX}/organizations/my",
headers={"Authorization": f"Bearer {token}"},
)
print(f"\n{'='*70}")
print(f"📋 GET /api/v1/organizations/my")
print(f"{'='*70}")
print(f"Status: {resp.status_code}")
if resp.status_code != 200:
print(f"❌ Error: {resp.text}")
return []
data = resp.json()
print(f"Count: {len(data)} organizations found")
print(f"\nRaw response:")
print(json.dumps(data, indent=2, default=str))
return data
async def list_members(token: str, org_id: int) -> list:
"""GET /api/v1/organizations/{org_id}/members - Tagok listázása."""
async with httpx.AsyncClient(base_url=BASE_URL) as client:
resp = await client.get(
f"{API_PREFIX}/organizations/{org_id}/members",
headers={"Authorization": f"Bearer {token}"},
)
print(f"\n{'='*70}")
print(f"📋 GET /api/v1/organizations/{org_id}/members")
print(f"{'='*70}")
print(f"Status: {resp.status_code}")
if resp.status_code != 200:
print(f"❌ Error: {resp.text}")
return []
data = resp.json()
print(f"Count: {len(data)} members")
print(json.dumps(data, indent=2, default=str))
return data
async def create_invitation(token: str, org_id: int, email: str, role: str = "MANAGER") -> dict:
"""POST /api/v1/organizations/{org_id}/invitations - Meghívó küldése."""
async with httpx.AsyncClient(base_url=BASE_URL) as client:
resp = await client.post(
f"{API_PREFIX}/organizations/{org_id}/invitations",
headers={"Authorization": f"Bearer {token}"},
json={"email": email, "role": role},
)
print(f"\n{'='*70}")
print(f"📋 POST /api/v1/organizations/{org_id}/invitations (email={email}, role={role})")
print(f"{'='*70}")
print(f"Status: {resp.status_code}")
print(f"Response: {resp.text}")
if resp.status_code in (200, 201):
return resp.json()
return None
async def update_member_role(token: str, org_id: int, member_id: int, role: str) -> dict:
"""PATCH /api/v1/organizations/{org_id}/members/{member_id} - Szerepkör módosítása."""
async with httpx.AsyncClient(base_url=BASE_URL) as client:
resp = await client.patch(
f"{API_PREFIX}/organizations/{org_id}/members/{member_id}",
headers={"Authorization": f"Bearer {token}"},
json={"role": role},
)
print(f"\n{'='*70}")
print(f"📋 PATCH /api/v1/organizations/{org_id}/members/{member_id} (role={role})")
print(f"{'='*70}")
print(f"Status: {resp.status_code}")
print(f"Response: {resp.text}")
if resp.status_code == 200:
return resp.json()
return None
async def remove_member(token: str, org_id: int, member_id: int) -> dict:
"""DELETE /api/v1/organizations/{org_id}/members/{member_id} - Tag eltávolítása."""
async with httpx.AsyncClient(base_url=BASE_URL) as client:
resp = await client.delete(
f"{API_PREFIX}/organizations/{org_id}/members/{member_id}",
headers={"Authorization": f"Bearer {token}"},
)
print(f"\n{'='*70}")
print(f"📋 DELETE /api/v1/organizations/{org_id}/members/{member_id}")
print(f"{'='*70}")
print(f"Status: {resp.status_code}")
print(f"Response: {resp.text}")
if resp.status_code == 200:
return resp.json()
return None
async def main():
print("=" * 70)
print("🔍 P0 GARAGE SELECTOR FIX & TEAM MANAGEMENT API TESZT")
print("=" * 70)
# 1. Bejelentkezés admin@profibot.hu (Vezető Tervező, user_id=2)
token = await login("admin@profibot.hu", "Admin123!")
# 2. Saját szervezetek lekérése
orgs = await get_my_organizations(token)
if not orgs:
print("\n❌ CRITICAL: No organizations returned! Garage Selector would be empty!")
print(" This means the get_my_organizations query is still broken.")
sys.exit(1)
# 3. Ellenőrizzük, hogy van-e olyan org ahol owner_id=2 (admin user)
admin_owned = [o for o in orgs if o.get("owner_id") == 2]
if admin_owned:
print(f"\n✅ Garage Selector FIX VERIFIED: {len(admin_owned)} organization(s) where owner_id=2:")
for o in admin_owned:
print(f" - ID: {o['organization_id']}, Name: {o.get('name', 'N/A')}, Role: {o.get('user_role', 'N/A')}")
else:
print(f"\n⚠️ No organizations found with owner_id=2. Checking all orgs...")
for o in orgs:
print(f" - ID: {o['organization_id']}, Name: {o.get('name', 'N/A')}, Owner: {o.get('owner_id', 'N/A')}, Role: {o.get('user_role', 'N/A')}")
# 4. Ha van legalább egy szervezet, teszteljük a Team Management API-t
if orgs:
test_org_id = orgs[0]["organization_id"]
print(f"\n{'='*70}")
print(f"🧪 TEAM MANAGEMENT API TESZTEK (org_id={test_org_id})")
print(f"{'='*70}")
# 4a. Tagok listázása
members = await list_members(token, test_org_id)
# 4b. Meghívó küldése egy nem létező emailre (invited_email teszt)
test_email = f"test_invite_{datetime.now(timezone.utc).timestamp()}@example.com"
invite_result = await create_invitation(token, test_org_id, test_email, "MANAGER")
if invite_result:
print(f"\n✅ Invitation created successfully!")
# 4c. Tagok újralistázása (ellenőrizzük, hogy megjelent-e a meghívó)
members_after = await list_members(token, test_org_id)
# Keressük az új meghívót
pending_invites = [m for m in members_after if m.get("status") == "pending"]
if pending_invites:
print(f"\n✅ Pending invitation found in member list!")
new_member_id = pending_invites[0]["id"]
# 4d. Szerepkör módosítása
role_result = await update_member_role(token, test_org_id, new_member_id, "ADMIN")
if role_result:
print(f"\n✅ Role update successful!")
# 4e. Tag eltávolítása (meghívó visszavonása)
remove_result = await remove_member(token, test_org_id, new_member_id)
if remove_result:
print(f"\n✅ Member removal successful!")
else:
print(f"\n⚠️ No pending invitations found in member list.")
else:
print(f"\n⚠️ Could not create test invitation (might already exist).")
print(f"\n{'='*70}")
print("✅ TESZT BEFEJEZŐDÖTT")
print(f"{'='*70}")
if __name__ == "__main__":
asyncio.run(main())