2026.03.29 20:00 Gitea_manager javítás előtt

This commit is contained in:
Roo
2026-03-29 17:59:06 +00:00
parent 03258db091
commit ba8b6579ef
148 changed files with 7951 additions and 591 deletions

View File

@@ -0,0 +1,282 @@
#!/usr/bin/env python3
"""
E2E Smoke Test for Registration Flow
Performs a complete "Blind Test" of the registration-to-activation flow.
"""
import asyncio
import uuid
import httpx
import json
import time
from datetime import datetime
from typing import Dict, Any, Optional
import sys
# Configuration
API_BASE_URL = "http://sf_api:8000/api/v1"
MAILPIT_API = "http://sf_mailpit:8025/api/v1"
def generate_unique_email() -> str:
"""Generate a unique email for testing."""
timestamp = int(time.time())
random_id = uuid.uuid4().hex[:8]
return f"test_{timestamp}_{random_id}@example.com"
async def call_registration(email: str) -> Dict[str, Any]:
"""Call the registration API endpoint."""
async with httpx.AsyncClient(timeout=30.0) as client:
payload = {
"email": email,
"password": "TestPassword123!",
"first_name": "Test",
"last_name": "User",
"region_code": "HU",
"lang": "hu"
}
print(f"📝 Registering user with email: {email}")
response = await client.post(f"{API_BASE_URL}/auth/register", json=payload)
if response.status_code != 201:
print(f"❌ Registration failed: {response.status_code}")
print(f"Response: {response.text}")
return {"success": False, "error": f"HTTP {response.status_code}"}
data = response.json()
print(f"✅ Registration successful: {data.get('message')}")
print(f" User ID: {data.get('user_id')}")
return {"success": True, "data": data}
async def get_verification_token_from_db(email: str) -> Optional[str]:
"""Get verification token directly from the database."""
import os
import asyncpg
# Database connection parameters from environment
db_host = os.getenv("DB_HOST", "shared-postgres")
db_name = os.getenv("DB_NAME", "service_finder")
db_user = os.getenv("DB_USER", "service_finder_app")
db_password = os.getenv("DB_PASSWORD", "JELSZAVAD")
try:
# Connect to database
conn = await asyncpg.connect(
host=db_host,
database=db_name,
user=db_user,
password=db_password
)
# Get user ID from email
user_row = await conn.fetchrow(
"SELECT id FROM identity.users WHERE email = $1",
email
)
if not user_row:
print(f"❌ User not found in database for email: {email}")
return None
user_id = user_row['id']
# Get verification token
token_row = await conn.fetchrow(
"""SELECT token FROM identity.verification_tokens
WHERE user_id = $1 AND token_type = 'registration'
ORDER BY created_at DESC LIMIT 1""",
user_id
)
await conn.close()
if token_row:
token = str(token_row['token'])
print(f"🔑 Found verification token in DB: {token[:8]}...")
return token
else:
print("❌ No verification token found in database")
return None
except Exception as e:
print(f"❌ Database error: {e}")
return None
async def get_verification_token_from_mailpit(email: str) -> Optional[str]:
"""Try to get verification token from Mailpit API."""
try:
async with httpx.AsyncClient(timeout=10.0) as client:
# Get latest messages
response = await client.get(f"{MAILPIT_API}/messages")
if response.status_code != 200:
print(f"❌ Mailpit API error: {response.status_code}")
return None
messages = response.json().get('messages', [])
# Find message sent to our test email
for msg in messages:
if msg.get('To', [{}])[0].get('Address') == email:
msg_id = msg['ID']
# Get message details
msg_response = await client.get(f"{MAILPIT_API}/message/{msg_id}")
if msg_response.status_code == 200:
msg_data = msg_response.json()
html = msg_data.get('HTML', '')
# Extract token from HTML (look for token= parameter)
import re
token_match = re.search(r'token=([a-f0-9\-]+)', html)
if token_match:
token = token_match.group(1)
print(f"📧 Found verification token in email: {token[:8]}...")
return token
# Also check text body
text = msg_data.get('Text', '')
token_match = re.search(r'token=([a-f0-9\-]+)', text)
if token_match:
token = token_match.group(1)
print(f"📧 Found verification token in email text: {token[:8]}...")
return token
print("❌ No email found in Mailpit for the test address")
return None
except Exception as e:
print(f"❌ Mailpit error: {e}")
return None
async def verify_email(token: str) -> bool:
"""Call the verify-email endpoint."""
async with httpx.AsyncClient(timeout=30.0) as client:
payload = {"token": token}
print(f"🔐 Verifying email with token: {token[:8]}...")
response = await client.post(f"{API_BASE_URL}/auth/verify-email", json=payload)
if response.status_code != 200:
print(f"❌ Email verification failed: {response.status_code}")
print(f"Response: {response.text}")
return False
data = response.json()
print(f"✅ Email verification successful: {data.get('message')}")
return True
async def check_user_activated(email: str) -> bool:
"""Check if user is activated in database."""
import os
import asyncpg
db_host = os.getenv("DB_HOST", "shared-postgres")
db_name = os.getenv("DB_NAME", "service_finder")
db_user = os.getenv("DB_USER", "service_finder_app")
db_password = os.getenv("DB_PASSWORD", "JELSZAVAD")
try:
conn = await asyncpg.connect(
host=db_host,
database=db_name,
user=db_user,
password=db_password
)
user_row = await conn.fetchrow(
"SELECT is_active FROM identity.users WHERE email = $1",
email
)
await conn.close()
if user_row:
is_active = user_row['is_active']
print(f"👤 User activation status: {'ACTIVE' if is_active else 'INACTIVE'}")
return is_active
else:
print("❌ User not found when checking activation")
return False
except Exception as e:
print(f"❌ Database error checking activation: {e}")
return False
async def main():
"""Main test execution."""
print("=" * 60)
print("🚀 Service Finder Registration E2E Smoke Test")
print("=" * 60)
# Generate unique test email
test_email = generate_unique_email()
print(f"📧 Test email: {test_email}")
# Step 1: Register user
print("\n1⃣ Step 1: Registration")
reg_result = await call_registration(test_email)
if not reg_result["success"]:
print("❌ TEST FAILED: Registration failed")
return False
# Wait a moment for email to be sent
print("\n⏳ Waiting 3 seconds for email processing...")
await asyncio.sleep(3)
# Step 2: Get verification token
print("\n2⃣ Step 2: Token Retrieval")
# Try database first (more reliable)
token = await get_verification_token_from_db(test_email)
# If not found in DB, try Mailpit
if not token:
print("⚠️ Token not found in DB, trying Mailpit...")
token = await get_verification_token_from_mailpit(test_email)
if not token:
print("❌ TEST FAILED: Could not retrieve verification token")
return False
# Step 3: Verify email
print("\n3⃣ Step 3: Email Verification")
verify_success = await verify_email(token)
if not verify_success:
print("❌ TEST FAILED: Email verification failed")
return False
# Step 4: Check user activation
print("\n4⃣ Step 4: Activation Verification")
await asyncio.sleep(2) # Give DB time to update
is_active = await check_user_activated(test_email)
if not is_active:
print("❌ TEST FAILED: User not activated after verification")
return False
# Final report
print("\n" + "=" * 60)
print("✅ TEST PASSED: Registration-to-Activation flow is 100% OK")
print("=" * 60)
print(f"Summary:")
print(f" • Test email: {test_email}")
print(f" • Registration: ✅ Success")
print(f" • Token retrieval: ✅ Success")
print(f" • Email verification: ✅ Success")
print(f" • User activation: ✅ Success")
print("=" * 60)
return True
if __name__ == "__main__":
# Install asyncpg if needed
try:
import asyncpg
except ImportError:
print("⚠️ asyncpg not installed. Installing...")
import subprocess
subprocess.check_call([sys.executable, "-m", "pip", "install", "asyncpg"])
import asyncpg
# Run the test
success = asyncio.run(main())
sys.exit(0 if success else 1)