feat(phase-6): Complete testing and deployment setup
Testing: - Add pytest configuration (pytest.ini) - Add test fixtures (tests/conftest.py) - Add ContentGenerator tests (13 tests) - Add ContentScheduler tests (16 tests) - Add PublisherManager tests (16 tests) - All 45 tests passing Production Docker: - Add docker-compose.prod.yml with healthchecks, resource limits - Add Dockerfile.prod with multi-stage build, non-root user - Add nginx.prod.conf with SSL, rate limiting, security headers - Add .env.prod.example template Maintenance Scripts: - Add backup.sh for database and media backups - Add restore.sh for database restoration - Add cleanup.sh for log rotation and Docker cleanup - Add healthcheck.sh with Telegram alerts Documentation: - Add DEPLOY.md with complete deployment guide Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
124
tests/conftest.py
Normal file
124
tests/conftest.py
Normal file
@@ -0,0 +1,124 @@
|
||||
"""
|
||||
Test fixtures and configuration.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, AsyncMock, patch
|
||||
from datetime import datetime, timedelta
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from app.core.database import Base
|
||||
|
||||
|
||||
# In-memory SQLite for testing
|
||||
TEST_DATABASE_URL = "sqlite:///:memory:"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_engine():
|
||||
"""Create an in-memory SQLite engine for testing."""
|
||||
engine = create_engine(
|
||||
TEST_DATABASE_URL,
|
||||
connect_args={"check_same_thread": False}
|
||||
)
|
||||
Base.metadata.create_all(bind=engine)
|
||||
yield engine
|
||||
Base.metadata.drop_all(bind=engine)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_session(test_engine):
|
||||
"""Create a test database session."""
|
||||
TestSessionLocal = sessionmaker(
|
||||
autocommit=False, autoflush=False, bind=test_engine
|
||||
)
|
||||
session = TestSessionLocal()
|
||||
yield session
|
||||
session.close()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_openai_client():
|
||||
"""Mock OpenAI client for DeepSeek API tests."""
|
||||
mock_client = MagicMock()
|
||||
|
||||
mock_response = MagicMock()
|
||||
mock_response.choices = [MagicMock()]
|
||||
mock_response.choices[0].message.content = "Generated test content #TechTip #AI"
|
||||
|
||||
mock_client.chat.completions.create.return_value = mock_response
|
||||
|
||||
return mock_client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_httpx_client():
|
||||
"""Mock httpx client for API calls."""
|
||||
mock_client = AsyncMock()
|
||||
mock_response = AsyncMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {"id": "123", "success": True}
|
||||
mock_client.get.return_value = mock_response
|
||||
mock_client.post.return_value = mock_response
|
||||
return mock_client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_product():
|
||||
"""Sample product data for testing."""
|
||||
return {
|
||||
"name": "Laptop HP Pavilion",
|
||||
"description": "Laptop potente para trabajo y gaming",
|
||||
"price": 15999.00,
|
||||
"category": "laptops",
|
||||
"specs": {
|
||||
"processor": "Intel Core i5",
|
||||
"ram": "16GB",
|
||||
"storage": "512GB SSD"
|
||||
},
|
||||
"highlights": ["Alta velocidad", "Diseño compacto", "Garantía 2 años"]
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_service():
|
||||
"""Sample service data for testing."""
|
||||
return {
|
||||
"name": "Automatización con IA",
|
||||
"description": "Automatiza tus procesos con inteligencia artificial",
|
||||
"category": "ai_automation",
|
||||
"target_sectors": ["retail", "manufactura", "servicios"],
|
||||
"benefits": ["Reduce costos", "Aumenta productividad", "24/7 operación"],
|
||||
"call_to_action": "Agenda una demo gratuita"
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_interaction():
|
||||
"""Sample interaction data for testing."""
|
||||
return {
|
||||
"content": "¿Qué procesador recomiendas para edición de video?",
|
||||
"type": "comment",
|
||||
"platform": "x",
|
||||
"author": "user123"
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_settings():
|
||||
"""Mock settings for testing."""
|
||||
with patch('app.core.config.settings') as mock:
|
||||
mock.DEEPSEEK_API_KEY = "test-api-key"
|
||||
mock.DEEPSEEK_BASE_URL = "https://api.deepseek.com"
|
||||
mock.BUSINESS_NAME = "Consultoría AS"
|
||||
mock.BUSINESS_LOCATION = "Tijuana, México"
|
||||
mock.BUSINESS_WEBSITE = "https://consultoria-as.com"
|
||||
mock.CONTENT_TONE = "Profesional pero accesible"
|
||||
yield mock
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fixed_datetime():
|
||||
"""Fixed datetime for consistent testing."""
|
||||
return datetime(2024, 6, 15, 10, 0, 0) # Saturday 10:00
|
||||
Reference in New Issue
Block a user