✨ New Features: - AI-powered habit creation with natural language processing - HuggingFace transformers integration for sentiment analysis (tracked via Git LFS) - Advanced predictive analytics and behavioral insights - Voice & image input capabilities for hands-free habit tracking - Real-time notifications and community features - Plugin system with extensible architecture 🔧 Technical Improvements: - Comprehensive FastAPI backend with 30+ endpoints - React frontend with PWA capabilities - Advanced authentication with 2FA support - RBAC authorization system - Comprehensive security features (CSRF, rate limiting, audit logging) - Database migrations and health monitoring - Docker containerization support - Git LFS configured for large AI model files (2+ GB) 📚 Documentation & DevOps: - Complete deployment guides for multiple platforms - Professional README with feature highlights - GitHub Actions CI/CD workflows - Comprehensive API documentation - Security audit roadmap and compliance framework - Setup scripts for development environment 🧪 Testing & Quality: - Comprehensive test suite with 20+ test modules - Setup verification scripts - Working development environment with both backend and frontend - Health checks and monitoring systems 🌟 Ready for: - Portfolio showcasing - Community contributions - Production deployment - Professional presentation
145 lines
4.8 KiB
Python
145 lines
4.8 KiB
Python
"""
|
|
Secure test data utilities - no hardcoded credentials
|
|
"""
|
|
import secrets
|
|
import string
|
|
from typing import Dict, Any
|
|
import bcrypt
|
|
from datetime import datetime, timedelta
|
|
|
|
|
|
class SecureTestDataGenerator:
|
|
"""Generate secure test data dynamically"""
|
|
|
|
def __init__(self):
|
|
self.session_data = {} # Store data for test session
|
|
|
|
def generate_secure_password(self, length: int = 12) -> str:
|
|
"""Generate a secure random password"""
|
|
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
|
|
return ''.join(secrets.choice(alphabet) for _ in range(length))
|
|
|
|
def generate_email(self, domain: str = "test.example.com") -> str:
|
|
"""Generate a unique test email"""
|
|
username = secrets.token_hex(8)
|
|
return f"test-{username}@{domain}"
|
|
|
|
def generate_jwt_secret(self) -> str:
|
|
"""Generate a secure JWT secret for testing"""
|
|
return secrets.token_urlsafe(64)
|
|
|
|
def generate_user_data(self, role: str = "user") -> Dict[str, Any]:
|
|
"""Generate secure test user data"""
|
|
password = self.generate_secure_password()
|
|
email = self.generate_email()
|
|
|
|
user_data = {
|
|
"email": email,
|
|
"password": password,
|
|
"password_hash": bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode(),
|
|
"display_name": f"Test User {secrets.token_hex(4)}",
|
|
"role": role,
|
|
"created_at": datetime.utcnow(),
|
|
}
|
|
|
|
# Store for test session
|
|
self.session_data[f"user_{email}"] = user_data
|
|
return user_data
|
|
|
|
def generate_habit_data(self, user_id: int) -> Dict[str, Any]:
|
|
"""Generate test habit data"""
|
|
habits = [
|
|
"Read for 30 minutes",
|
|
"Exercise for 45 minutes",
|
|
"Meditate for 10 minutes",
|
|
"Write in journal",
|
|
"Practice coding",
|
|
]
|
|
|
|
return {
|
|
"title": f"{secrets.choice(habits)} - {secrets.token_hex(2)}",
|
|
"description": f"Test habit description {secrets.token_hex(4)}",
|
|
"user_id": user_id,
|
|
"category": secrets.choice(["health", "productivity", "learning", "mindfulness"]),
|
|
"difficulty": secrets.randbelow(5) + 1,
|
|
"created_at": datetime.utcnow(),
|
|
}
|
|
|
|
def generate_project_data(self, user_id: int) -> Dict[str, Any]:
|
|
"""Generate test project data"""
|
|
projects = [
|
|
"Build a personal website",
|
|
"Learn a new programming language",
|
|
"Complete online course",
|
|
"Write a blog post",
|
|
"Create a mobile app",
|
|
]
|
|
|
|
return {
|
|
"title": f"{secrets.choice(projects)} - {secrets.token_hex(2)}",
|
|
"description": f"Test project description {secrets.token_hex(6)}",
|
|
"user_id": user_id,
|
|
"created_at": datetime.utcnow(),
|
|
"due_date": datetime.utcnow() + timedelta(days=secrets.randbelow(90) + 1),
|
|
}
|
|
|
|
def generate_api_token(self, user_id: int) -> Dict[str, Any]:
|
|
"""Generate test API token"""
|
|
return {
|
|
"name": f"Test Token {secrets.token_hex(3)}",
|
|
"token": secrets.token_urlsafe(32),
|
|
"user_id": user_id,
|
|
"permissions": ["read:habits", "read:projects"],
|
|
"expires_at": datetime.utcnow() + timedelta(days=30),
|
|
"created_at": datetime.utcnow(),
|
|
}
|
|
|
|
def cleanup_session_data(self):
|
|
"""Clear all session test data"""
|
|
self.session_data.clear()
|
|
|
|
def get_test_database_url(self) -> str:
|
|
"""Generate isolated test database URL"""
|
|
db_name = f"test_liferpg_{secrets.token_hex(8)}"
|
|
return f"sqlite:///./{db_name}.db"
|
|
|
|
|
|
# Global test data generator
|
|
test_data_generator = SecureTestDataGenerator()
|
|
|
|
|
|
def create_test_environment():
|
|
"""Set up secure test environment variables"""
|
|
import os
|
|
|
|
# Only set if not already configured
|
|
test_env = {
|
|
"LIFERPG_JWT_SECRET": test_data_generator.generate_jwt_secret(),
|
|
"DATABASE_URL": test_data_generator.get_test_database_url(),
|
|
"ENVIRONMENT": "test",
|
|
"CSRF_ENABLE": "false", # Disable CSRF for API tests
|
|
"RATE_LIMIT_PER_MINUTE": "1000", # Higher limit for tests
|
|
"ENCRYPTION_KEY": secrets.token_urlsafe(32),
|
|
}
|
|
|
|
for key, value in test_env.items():
|
|
if key not in os.environ:
|
|
os.environ[key] = value
|
|
|
|
return test_env
|
|
|
|
|
|
def cleanup_test_environment():
|
|
"""Clean up test environment"""
|
|
import os
|
|
|
|
# Remove test database files
|
|
test_files = [f for f in os.listdir('.') if f.startswith('test_liferpg_') and f.endswith('.db')]
|
|
for file in test_files:
|
|
try:
|
|
os.remove(file)
|
|
except OSError:
|
|
pass
|
|
|
|
# Clear test data
|
|
test_data_generator.cleanup_session_data() |