Files
GitMa/backend/tests/conftest.py
panw 44921c5646 feat: complete Git Repo Manager MVP implementation
Backend (Phase 1-6):
- Pydantic schemas for request/response validation
- Service layer (SSH Key, Server, Repo, Sync)
- API routes with authentication
- FastAPI main application with lifespan management
- ORM models (SshKey, Server, Repo, SyncLog)

Frontend (Phase 7):
- Vue 3 + Element Plus + Pinia + Vue Router
- API client with Axios and interceptors
- State management stores
- All page components (Dashboard, Servers, Repos, SyncLogs, SshKeys, Settings)

Deployment (Phase 8):
- README with quick start guide
- Startup script (start.sh)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 16:30:13 +08:00

130 lines
3.7 KiB
Python

import sys
import pytest
from pathlib import Path
from typing import Generator
# Add backend to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session
# NOTE: This import will fail until models are created in Task 2.1
# This is expected behavior - the models module doesn't exist yet
from app.models import Base
@pytest.fixture(scope="function")
def db_path(tmp_path):
"""临时数据库路径."""
return tmp_path / "test.db"
@pytest.fixture(scope="function")
def db_engine(db_path):
"""临时数据库引擎."""
engine = create_engine(f"sqlite:///{db_path}", connect_args={"check_same_thread": False})
Base.metadata.create_all(engine)
yield engine
engine.dispose()
@pytest.fixture(scope="function")
def db_session(db_engine):
"""临时数据库会话."""
SessionLocal = sessionmaker(bind=db_engine, autocommit=False, autoflush=False)
session = SessionLocal()
yield session
session.close()
@pytest.fixture(scope="function")
def test_encrypt_key():
"""测试加密密钥."""
import base64
return base64.b64encode(b'test-key-32-bytes-long-123456789').decode()
@pytest.fixture(scope="function")
def test_env_vars(db_path, test_encrypt_key, monkeypatch):
"""设置测试环境变量."""
# Clear global settings to ensure fresh config
import app.config
app.config._settings = None
monkeypatch.setenv("GM_ENCRYPT_KEY", test_encrypt_key)
monkeypatch.setenv("GM_API_TOKEN", "test-token")
monkeypatch.setenv("GM_DATA_DIR", str(db_path.parent))
return {
"GM_ENCRYPT_KEY": test_encrypt_key,
"GM_API_TOKEN": "test-token",
}
@pytest.fixture(scope="function")
def client(db_session: Session, test_env_vars: dict, monkeypatch):
"""
FastAPI test client fixture.
Provides a test client for the FastAPI application with:
- In-memory database session
- Test environment variables
- Disabled lifespan (for faster tests)
Args:
db_session: Database session fixture
test_env_vars: Test environment variables fixture
monkeypatch: Pytest monkeypatch fixture
Yields:
FastAPI test client
Example:
def test_create_ssh_key(client):
response = client.post(
"/api/ssh-keys",
json={"name": "test-key", "private_key": "..."},
headers={"Authorization": "Bearer test-token"}
)
assert response.status_code == 201
"""
from fastapi.testclient import TestClient
from unittest.mock import AsyncMock, patch
# Mock the lifespan context manager
async def mock_lifespan(app): # noqa: ARG001 - Unused app parameter
# Database is already initialized by db_session fixture
yield
# Import after setting env vars
import app.database
import app.config
# Initialize database with test session
app.database._engine = db_session.bind
app.database._session_factory = sessionmaker(bind=db_session.bind, autocommit=False, autoflush=False)
# Create app with mocked lifespan
from app.main import create_app
test_app = create_app(lifespan_handler=mock_lifespan)
# Override get_db_session dependency to use test session
from app.api import deps
def override_get_db_session():
try:
yield db_session
finally:
pass
test_app.dependency_overrides[deps.get_db_session] = override_get_db_session
with TestClient(test_app) as test_client:
yield test_client
# Clean up
test_app.dependency_overrides = {}
app.database._engine = None
app.database._session_factory = None
app.config._settings = None