ALwrity Version 0.5.0 (Fastapi + React )

This commit is contained in:
ajaysi
2025-08-06 12:48:02 +05:30
parent f28a919caa
commit 32f97fa6b3
476 changed files with 115544 additions and 28747 deletions

View File

@@ -0,0 +1,2 @@
# Import content planning endpoints
from api.content_planning import router as content_planning_router

View File

@@ -0,0 +1,177 @@
"""Test script for ALwrity backend."""
import requests
import json
import time
def test_backend():
"""Test the backend endpoints."""
base_url = "http://localhost:8000"
print("🧪 Testing ALwrity Backend API...")
# Test 1: Health check
print("\n1. Testing health check...")
try:
response = requests.get(f"{base_url}/health")
if response.status_code == 200:
print("✅ Health check passed")
print(f" Response: {response.json()}")
else:
print(f"❌ Health check failed: {response.status_code}")
except Exception as e:
print(f"❌ Health check error: {e}")
return False
# Test 2: Get onboarding status
print("\n2. Testing onboarding status...")
try:
response = requests.get(f"{base_url}/api/onboarding/status")
if response.status_code == 200:
print("✅ Onboarding status passed")
data = response.json()
print(f" Current step: {data.get('current_step')}")
print(f" Completion: {data.get('completion_percentage')}%")
else:
print(f"❌ Onboarding status failed: {response.status_code}")
except Exception as e:
print(f"❌ Onboarding status error: {e}")
return False
# Test 3: Get onboarding config
print("\n3. Testing onboarding config...")
try:
response = requests.get(f"{base_url}/api/onboarding/config")
if response.status_code == 200:
print("✅ Onboarding config passed")
data = response.json()
print(f" Total steps: {data.get('total_steps')}")
else:
print(f"❌ Onboarding config failed: {response.status_code}")
except Exception as e:
print(f"❌ Onboarding config error: {e}")
return False
# Test 4: Get API keys
print("\n4. Testing API keys endpoint...")
try:
response = requests.get(f"{base_url}/api/onboarding/api-keys")
if response.status_code == 200:
print("✅ API keys endpoint passed")
data = response.json()
print(f" Configured keys: {data.get('total_configured')}")
else:
print(f"❌ API keys endpoint failed: {response.status_code}")
except Exception as e:
print(f"❌ API keys endpoint error: {e}")
return False
# Test 5: Save API key
print("\n5. Testing save API key...")
try:
test_key_data = {
"provider": "openai",
"api_key": "sk-test1234567890abcdef",
"description": "Test API key"
}
response = requests.post(
f"{base_url}/api/onboarding/api-keys",
json=test_key_data,
headers={"Content-Type": "application/json"}
)
if response.status_code == 200:
print("✅ Save API key passed")
data = response.json()
print(f" Message: {data.get('message')}")
else:
print(f"❌ Save API key failed: {response.status_code}")
print(f" Response: {response.text}")
except Exception as e:
print(f"❌ Save API key error: {e}")
return False
# Test 6: Complete step
print("\n6. Testing complete step...")
try:
step_data = {
"data": {"api_keys": ["openai"]},
"validation_errors": []
}
response = requests.post(
f"{base_url}/api/onboarding/step/1/complete",
json=step_data,
headers={"Content-Type": "application/json"}
)
if response.status_code == 200:
print("✅ Complete step passed")
data = response.json()
print(f" Message: {data.get('message')}")
else:
print(f"❌ Complete step failed: {response.status_code}")
print(f" Response: {response.text}")
except Exception as e:
print(f"❌ Complete step error: {e}")
return False
# Test 7: Get updated status
print("\n7. Testing updated status...")
try:
response = requests.get(f"{base_url}/api/onboarding/status")
if response.status_code == 200:
print("✅ Updated status passed")
data = response.json()
print(f" Current step: {data.get('current_step')}")
print(f" Completion: {data.get('completion_percentage')}%")
else:
print(f"❌ Updated status failed: {response.status_code}")
except Exception as e:
print(f"❌ Updated status error: {e}")
return False
print("\n🎉 All tests completed!")
return True
def test_api_docs():
"""Test if API documentation is accessible."""
base_url = "http://localhost:8000"
print("\n📚 Testing API documentation...")
try:
# Test Swagger docs
response = requests.get(f"{base_url}/api/docs")
if response.status_code == 200:
print("✅ Swagger docs accessible")
else:
print(f"❌ Swagger docs failed: {response.status_code}")
# Test ReDoc
response = requests.get(f"{base_url}/api/redoc")
if response.status_code == 200:
print("✅ ReDoc accessible")
else:
print(f"❌ ReDoc failed: {response.status_code}")
except Exception as e:
print(f"❌ API docs error: {e}")
if __name__ == "__main__":
print("🚀 Starting ALwrity Backend Tests")
print("=" * 50)
# Wait a moment for server to start
print("⏳ Waiting for server to be ready...")
time.sleep(2)
# Run tests
success = test_backend()
test_api_docs()
if success:
print("\n✅ All tests passed! Backend is working correctly.")
print("\n📖 You can now:")
print(" - View API docs at: http://localhost:8000/api/docs")
print(" - Test endpoints manually")
print(" - Integrate with React frontend")
else:
print("\n❌ Some tests failed. Please check the backend logs.")

View File

@@ -0,0 +1,264 @@
#!/usr/bin/env python3
"""Test script for content planning services."""
import asyncio
from loguru import logger
# Import all content planning services
from services.content_gap_analyzer import ContentGapAnalyzer
from services.competitor_analyzer import CompetitorAnalyzer
from services.keyword_researcher import KeywordResearcher
from services.ai_engine_service import AIEngineService
from services.website_analyzer import WebsiteAnalyzer
async def test_content_planning_services():
"""Test all content planning services."""
logger.info("🧪 Testing Content Planning Services")
try:
# Test 1: Initialize all services
logger.info("1. Initializing services...")
content_gap_analyzer = ContentGapAnalyzer()
competitor_analyzer = CompetitorAnalyzer()
keyword_researcher = KeywordResearcher()
ai_engine = AIEngineService()
website_analyzer = WebsiteAnalyzer()
logger.info("✅ All services initialized successfully")
# Test 2: Test content gap analysis
logger.info("2. Testing content gap analysis...")
target_url = "https://alwrity.com"
competitor_urls = ["https://competitor1.com", "https://competitor2.com"]
target_keywords = ["content planning", "digital marketing", "seo strategy"]
gap_analysis = await content_gap_analyzer.analyze_comprehensive_gap(
target_url=target_url,
competitor_urls=competitor_urls,
target_keywords=target_keywords,
industry="technology"
)
if gap_analysis:
logger.info(f"✅ Content gap analysis completed: {len(gap_analysis.get('recommendations', []))} recommendations")
else:
logger.warning("⚠️ Content gap analysis returned empty results")
# Test 3: Test competitor analysis
logger.info("3. Testing competitor analysis...")
competitor_analysis = await competitor_analyzer.analyze_competitors(
competitor_urls=competitor_urls,
industry="technology"
)
if competitor_analysis:
logger.info(f"✅ Competitor analysis completed: {len(competitor_analysis.get('competitors', []))} competitors analyzed")
else:
logger.warning("⚠️ Competitor analysis returned empty results")
# Test 4: Test keyword research
logger.info("4. Testing keyword research...")
keyword_analysis = await keyword_researcher.analyze_keywords(
industry="technology",
url=target_url,
target_keywords=target_keywords
)
if keyword_analysis:
logger.info(f"✅ Keyword analysis completed: {len(keyword_analysis.get('opportunities', []))} opportunities found")
else:
logger.warning("⚠️ Keyword analysis returned empty results")
# Test 5: Test website analysis
logger.info("5. Testing website analysis...")
website_analysis = await website_analyzer.analyze_website(
url=target_url,
industry="technology"
)
if website_analysis:
logger.info(f"✅ Website analysis completed: {website_analysis.get('content_analysis', {}).get('total_pages', 0)} pages analyzed")
else:
logger.warning("⚠️ Website analysis returned empty results")
# Test 6: Test AI engine
logger.info("6. Testing AI engine...")
analysis_summary = {
'target_url': target_url,
'industry': 'technology',
'serp_opportunities': 5,
'expanded_keywords_count': 25,
'competitors_analyzed': 2,
'dominant_themes': ['content strategy', 'digital marketing', 'seo']
}
ai_insights = await ai_engine.analyze_content_gaps(analysis_summary)
if ai_insights:
logger.info(f"✅ AI insights generated: {len(ai_insights.get('strategic_insights', []))} insights")
else:
logger.warning("⚠️ AI insights returned empty results")
# Test 7: Test content quality analysis
logger.info("7. Testing content quality analysis...")
content_quality = await website_analyzer.analyze_content_quality(target_url)
if content_quality:
logger.info(f"✅ Content quality analysis completed: Score {content_quality.get('overall_quality_score', 0)}/10")
else:
logger.warning("⚠️ Content quality analysis returned empty results")
# Test 8: Test user experience analysis
logger.info("8. Testing user experience analysis...")
ux_analysis = await website_analyzer.analyze_user_experience(target_url)
if ux_analysis:
logger.info(f"✅ UX analysis completed: Score {ux_analysis.get('overall_ux_score', 0)}/10")
else:
logger.warning("⚠️ UX analysis returned empty results")
# Test 9: Test keyword expansion
logger.info("9. Testing keyword expansion...")
seed_keywords = ["content planning", "digital marketing"]
expanded_keywords = await keyword_researcher.expand_keywords(
seed_keywords=seed_keywords,
industry="technology"
)
if expanded_keywords:
logger.info(f"✅ Keyword expansion completed: {len(expanded_keywords.get('expanded_keywords', []))} keywords generated")
else:
logger.warning("⚠️ Keyword expansion returned empty results")
# Test 10: Test search intent analysis
logger.info("10. Testing search intent analysis...")
keywords = ["content planning guide", "digital marketing tips", "seo best practices"]
intent_analysis = await keyword_researcher.analyze_search_intent(keywords)
if intent_analysis:
logger.info(f"✅ Search intent analysis completed: {len(intent_analysis.get('keyword_intents', {}))} keywords analyzed")
else:
logger.warning("⚠️ Search intent analysis returned empty results")
logger.info("🎉 All content planning services tested successfully!")
return True
except Exception as e:
logger.error(f"❌ Error testing content planning services: {str(e)}")
return False
async def test_ai_engine_features():
"""Test specific AI engine features."""
logger.info("🤖 Testing AI Engine Features")
try:
ai_engine = AIEngineService()
# Test market position analysis
market_data = {
'competitors_analyzed': 3,
'avg_content_count': 150,
'avg_quality_score': 8.5,
'frequency_distribution': {'3x/week': 2, '2x/week': 1},
'industry': 'technology'
}
market_position = await ai_engine.analyze_market_position(market_data)
if market_position:
logger.info("✅ Market position analysis completed")
else:
logger.warning("⚠️ Market position analysis failed")
# Test content recommendations
analysis_data = {
'target_url': 'https://alwrity.com',
'industry': 'technology',
'keywords': ['content planning', 'digital marketing'],
'competitors': ['competitor1.com', 'competitor2.com']
}
recommendations = await ai_engine.generate_content_recommendations(analysis_data)
if recommendations:
logger.info(f"✅ Content recommendations generated: {len(recommendations)} recommendations")
else:
logger.warning("⚠️ Content recommendations failed")
# Test performance predictions
content_data = {
'content_type': 'blog_post',
'target_keywords': ['content planning'],
'industry': 'technology',
'content_length': 1500
}
predictions = await ai_engine.predict_content_performance(content_data)
if predictions:
logger.info("✅ Performance predictions generated")
else:
logger.warning("⚠️ Performance predictions failed")
# Test competitive intelligence
competitor_data = {
'competitors': ['competitor1.com', 'competitor2.com'],
'industry': 'technology',
'analysis_depth': 'comprehensive'
}
competitive_intelligence = await ai_engine.analyze_competitive_intelligence(competitor_data)
if competitive_intelligence:
logger.info("✅ Competitive intelligence analysis completed")
else:
logger.warning("⚠️ Competitive intelligence analysis failed")
# Test strategic insights
analysis_data = {
'industry': 'technology',
'target_audience': 'marketing professionals',
'business_goals': ['increase traffic', 'improve conversions'],
'current_performance': 'moderate'
}
strategic_insights = await ai_engine.generate_strategic_insights(analysis_data)
if strategic_insights:
logger.info(f"✅ Strategic insights generated: {len(strategic_insights)} insights")
else:
logger.warning("⚠️ Strategic insights failed")
# Test content quality analysis
content_data = {
'content_text': 'Sample content for analysis',
'target_keywords': ['content planning'],
'industry': 'technology'
}
quality_analysis = await ai_engine.analyze_content_quality(content_data)
if quality_analysis:
logger.info(f"✅ Content quality analysis completed: Score {quality_analysis.get('overall_quality_score', 0)}/10")
else:
logger.warning("⚠️ Content quality analysis failed")
logger.info("🎉 All AI engine features tested successfully!")
return True
except Exception as e:
logger.error(f"❌ Error testing AI engine features: {str(e)}")
return False
async def main():
"""Main test function."""
logger.info("🚀 Starting Content Planning Services Test Suite")
# Test 1: Basic services
services_result = await test_content_planning_services()
# Test 2: AI engine features
ai_result = await test_ai_engine_features()
if services_result and ai_result:
logger.info("🎉 All tests passed! Content Planning Services are ready for Phase 1 implementation.")
else:
logger.error("❌ Some tests failed. Please check the logs above.")
logger.info("🏁 Test suite completed")
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,139 @@
"""
Test script for database functionality.
"""
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from services.database import init_database, get_db_session, close_database
from services.website_analysis_service import WebsiteAnalysisService
from models.onboarding import WebsiteAnalysis, OnboardingSession
def test_database_functionality():
"""Test database initialization and basic operations."""
try:
print("Testing database functionality...")
# Initialize database
init_database()
print("✅ Database initialized successfully")
# Get database session
db_session = get_db_session()
if not db_session:
print("❌ Failed to get database session")
return False
print("✅ Database session created successfully")
# Test website analysis service
analysis_service = WebsiteAnalysisService(db_session)
print("✅ Website analysis service created successfully")
# Test creating a session
session = OnboardingSession(user_id=1, current_step=2, progress=25.0)
db_session.add(session)
db_session.commit()
print(f"✅ Created onboarding session with ID: {session.id}")
# Test saving analysis
test_analysis_data = {
'style_analysis': {
'writing_style': {
'tone': 'professional',
'voice': 'active',
'complexity': 'moderate',
'engagement_level': 'high'
},
'target_audience': {
'demographics': ['professionals', 'business owners'],
'expertise_level': 'intermediate',
'industry_focus': 'technology',
'geographic_focus': 'global'
},
'content_type': {
'primary_type': 'blog',
'secondary_types': ['article', 'guide'],
'purpose': 'informational',
'call_to_action': 'subscribe'
},
'recommended_settings': {
'writing_tone': 'professional',
'target_audience': 'business professionals',
'content_type': 'blog posts',
'creativity_level': 'balanced',
'geographic_location': 'global'
}
},
'crawl_result': {
'content': 'Sample website content...',
'word_count': 1500
},
'style_patterns': {
'sentence_length': 'medium',
'paragraph_structure': 'well-organized'
},
'style_guidelines': {
'tone_guidelines': 'Maintain professional tone',
'structure_guidelines': 'Use clear headings'
}
}
analysis_id = analysis_service.save_analysis(
session_id=session.id,
website_url='https://example.com',
analysis_data=test_analysis_data
)
if analysis_id:
print(f"✅ Saved analysis with ID: {analysis_id}")
else:
print("❌ Failed to save analysis")
return False
# Test retrieving analysis
analysis = analysis_service.get_analysis(analysis_id)
if analysis:
print("✅ Retrieved analysis successfully")
print(f" Website URL: {analysis['website_url']}")
print(f" Writing Style: {analysis['writing_style']['tone']}")
else:
print("❌ Failed to retrieve analysis")
return False
# Test checking existing analysis
existing_check = analysis_service.check_existing_analysis(
session_id=session.id,
website_url='https://example.com'
)
if existing_check and existing_check.get('exists'):
print("✅ Existing analysis check works")
else:
print("❌ Existing analysis check failed")
return False
# Clean up
if analysis_id:
analysis_service.delete_analysis(analysis_id)
db_session.delete(session)
db_session.commit()
print("✅ Cleanup completed")
print("\n🎉 All database tests passed!")
return True
except Exception as e:
print(f"❌ Database test failed: {str(e)}")
return False
finally:
close_database()
if __name__ == "__main__":
success = test_database_functionality()
if success:
print("\n✅ Database functionality is working correctly!")
else:
print("\n❌ Database functionality has issues!")
sys.exit(1)

View File

@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""
Test script for SEO analyzer integration
"""
import asyncio
import sys
import os
# Add the backend directory to the path
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from services.comprehensive_seo_analyzer import ComprehensiveSEOAnalyzer
from services.database import init_database, get_db_session
from services.seo_analysis_service import SEOAnalysisService
from loguru import logger
async def test_seo_analyzer():
"""Test the SEO analyzer functionality."""
print("🔍 Testing SEO Analyzer Integration")
print("=" * 50)
try:
# Initialize database
print("📊 Initializing database...")
init_database()
print("✅ Database initialized successfully")
# Test URL
test_url = "https://example.com"
print(f"🌐 Testing with URL: {test_url}")
# Create analyzer
analyzer = ComprehensiveSEOAnalyzer()
# Run analysis
print("🔍 Running comprehensive SEO analysis...")
result = analyzer.analyze_url(test_url)
print(f"📈 Analysis Results:")
print(f" URL: {result.url}")
print(f" Overall Score: {result.overall_score}/100")
print(f" Health Status: {result.health_status}")
print(f" Critical Issues: {len(result.critical_issues)}")
print(f" Warnings: {len(result.warnings)}")
print(f" Recommendations: {len(result.recommendations)}")
# Test database storage
print("\n💾 Testing database storage...")
db_session = get_db_session()
if db_session:
try:
seo_service = SEOAnalysisService(db_session)
stored_analysis = seo_service.store_analysis_result(result)
if stored_analysis:
print(f"✅ Analysis stored in database with ID: {stored_analysis.id}")
# Test retrieval
retrieved_analysis = seo_service.get_latest_analysis(test_url)
if retrieved_analysis:
print(f"✅ Analysis retrieved from database")
print(f" Stored Score: {retrieved_analysis.overall_score}")
print(f" Stored Status: {retrieved_analysis.health_status}")
else:
print("❌ Failed to retrieve analysis from database")
else:
print("❌ Failed to store analysis in database")
except Exception as e:
print(f"❌ Database error: {str(e)}")
finally:
db_session.close()
else:
print("❌ Failed to get database session")
# Test statistics
print("\n📊 Testing statistics...")
db_session = get_db_session()
if db_session:
try:
seo_service = SEOAnalysisService(db_session)
stats = seo_service.get_analysis_statistics()
print(f"📈 Analysis Statistics:")
print(f" Total Analyses: {stats['total_analyses']}")
print(f" Total URLs: {stats['total_urls']}")
print(f" Average Score: {stats['average_score']}")
print(f" Health Distribution: {stats['health_distribution']}")
except Exception as e:
print(f"❌ Statistics error: {str(e)}")
finally:
db_session.close()
print("\n🎉 SEO Analyzer Integration Test Completed!")
except Exception as e:
print(f"❌ Test failed: {str(e)}")
logger.error(f"Test failed: {str(e)}")
if __name__ == "__main__":
asyncio.run(test_seo_analyzer())

View File

@@ -0,0 +1,117 @@
"""
Test script to verify strategy data structure matches frontend expectations
"""
import asyncio
import json
from api.content_planning.services.strategy_service import StrategyService
async def test_strategy_data_structure():
"""Test the strategy data structure to ensure it matches frontend expectations."""
print("🧪 Testing Strategy Data Structure")
print("=" * 50)
# Initialize service
service = StrategyService()
# Get strategies
result = await service.get_strategies(user_id=1)
print("📊 Backend Response Structure:")
print(json.dumps(result, indent=2, default=str))
# Check if strategies array exists
if "strategies" in result and len(result["strategies"]) > 0:
strategy = result["strategies"][0]
print("\n✅ Frontend Expected Structure Check:")
print("-" * 40)
# Check for ai_recommendations
if "ai_recommendations" in strategy:
ai_rec = strategy["ai_recommendations"]
print(f"✅ ai_recommendations: Present")
# Check market_score
if "market_score" in ai_rec:
print(f"✅ market_score: {ai_rec['market_score']}")
else:
print("❌ market_score: Missing")
# Check strengths
if "strengths" in ai_rec:
print(f"✅ strengths: {len(ai_rec['strengths'])} items")
else:
print("❌ strengths: Missing")
# Check weaknesses
if "weaknesses" in ai_rec:
print(f"✅ weaknesses: {len(ai_rec['weaknesses'])} items")
else:
print("❌ weaknesses: Missing")
# Check competitive_advantages
if "competitive_advantages" in ai_rec:
print(f"✅ competitive_advantages: {len(ai_rec['competitive_advantages'])} items")
else:
print("❌ competitive_advantages: Missing")
# Check strategic_risks
if "strategic_risks" in ai_rec:
print(f"✅ strategic_risks: {len(ai_rec['strategic_risks'])} items")
else:
print("❌ strategic_risks: Missing")
else:
print("❌ ai_recommendations: Missing")
# Check for required strategy fields
required_fields = ["id", "name", "industry", "target_audience", "content_pillars"]
for field in required_fields:
if field in strategy:
print(f"{field}: Present")
else:
print(f"{field}: Missing")
print("\n🎯 Frontend Data Mapping Validation:")
print("-" * 40)
# Validate the specific structure expected by frontend
if "ai_recommendations" in strategy:
ai_rec = strategy["ai_recommendations"]
# Check market positioning structure
if "market_score" in ai_rec:
print(f"✅ Frontend can access: strategy.ai_recommendations.market_score")
# Check strengths structure
if "strengths" in ai_rec and isinstance(ai_rec["strengths"], list):
print(f"✅ Frontend can access: strategy.ai_recommendations.strengths")
# Check weaknesses structure
if "weaknesses" in ai_rec and isinstance(ai_rec["weaknesses"], list):
print(f"✅ Frontend can access: strategy.ai_recommendations.weaknesses")
# Check competitive advantages structure
if "competitive_advantages" in ai_rec and isinstance(ai_rec["competitive_advantages"], list):
print(f"✅ Frontend can access: strategy.ai_recommendations.competitive_advantages")
# Check strategic risks structure
if "strategic_risks" in ai_rec and isinstance(ai_rec["strategic_risks"], list):
print(f"✅ Frontend can access: strategy.ai_recommendations.strategic_risks")
print("\n🎉 Data Structure Validation Complete!")
print("=" * 50)
return True
else:
print("❌ No strategies found in response")
return False
if __name__ == "__main__":
success = asyncio.run(test_strategy_data_structure())
if success:
print("✅ All tests passed! Backend data structure matches frontend expectations.")
else:
print("❌ Tests failed! Backend data structure needs adjustment.")

View File

@@ -0,0 +1,82 @@
#!/usr/bin/env python3
"""
Test script for user data service
"""
import sys
import os
# Add the backend directory to the path
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from services.database import init_database, get_db_session
from services.user_data_service import UserDataService
from loguru import logger
def test_user_data():
"""Test the user data service functionality."""
print("👤 Testing User Data Service")
print("=" * 50)
try:
# Initialize database
print("📊 Initializing database...")
init_database()
print("✅ Database initialized successfully")
# Test fetching user website URL
print("\n🌐 Testing website URL fetching...")
db_session = get_db_session()
if db_session:
try:
user_data_service = UserDataService(db_session)
website_url = user_data_service.get_user_website_url()
if website_url:
print(f"✅ Found website URL: {website_url}")
else:
print("⚠️ No website URL found in database")
print(" This is expected if no onboarding has been completed yet")
# Test getting full onboarding data
print("\n📋 Testing full onboarding data...")
onboarding_data = user_data_service.get_user_onboarding_data()
if onboarding_data:
print("✅ Found onboarding data:")
print(f" Session ID: {onboarding_data['session']['id']}")
print(f" Current Step: {onboarding_data['session']['current_step']}")
print(f" Progress: {onboarding_data['session']['progress']}")
if onboarding_data['website_analysis']:
print(f" Website URL: {onboarding_data['website_analysis']['website_url']}")
print(f" Analysis Status: {onboarding_data['website_analysis']['status']}")
else:
print(" No website analysis found")
print(f" API Keys: {len(onboarding_data['api_keys'])} configured")
if onboarding_data['research_preferences']:
print(" Research preferences configured")
else:
print(" No research preferences found")
else:
print("⚠️ No onboarding data found")
print(" This is expected if no onboarding has been completed yet")
except Exception as e:
print(f"❌ Database error: {str(e)}")
finally:
db_session.close()
else:
print("❌ Failed to get database session")
print("\n🎉 User Data Service Test Completed!")
except Exception as e:
print(f"❌ Test failed: {str(e)}")
logger.error(f"Test failed: {str(e)}")
if __name__ == "__main__":
test_user_data()