ALwrity Version 0.5.0 (Fastapi + React )
This commit is contained in:
2
backend/test/temp_import.txt
Normal file
2
backend/test/temp_import.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# Import content planning endpoints
|
||||
from api.content_planning import router as content_planning_router
|
||||
177
backend/test/test_backend.py
Normal file
177
backend/test/test_backend.py
Normal 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.")
|
||||
264
backend/test/test_content_planning_services.py
Normal file
264
backend/test/test_content_planning_services.py
Normal 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())
|
||||
139
backend/test/test_database.py
Normal file
139
backend/test/test_database.py
Normal 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)
|
||||
102
backend/test/test_seo_integration.py
Normal file
102
backend/test/test_seo_integration.py
Normal 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())
|
||||
117
backend/test/test_strategy_data_structure.py
Normal file
117
backend/test/test_strategy_data_structure.py
Normal 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.")
|
||||
82
backend/test/test_user_data.py
Normal file
82
backend/test/test_user_data.py
Normal 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()
|
||||
Reference in New Issue
Block a user