MemPrepMate / tests /conftest.py
Christian Kniep
new webapp
1fff71f
raw
history blame
6.06 kB
"""
Pytest configuration and fixtures for webapp testing.
Feature: 012-profile-contact-ui
"""
import os
import sqlite3
import tempfile
from typing import Generator
import pytest
from flask import Flask
from flask.testing import FlaskClient
# Set test environment variables before importing app
os.environ["SECRET_KEY"] = "test-secret-key"
os.environ["BACKEND_API_URL"] = "http://test-api:8080/v1"
os.environ["HF_CLIENT_ID"] = "test-client-id"
os.environ["HF_CLIENT_SECRET"] = "test-client-secret"
os.environ["HF_REDIRECT_URI"] = "http://localhost:5000/callback"
@pytest.fixture
def app() -> Generator[Flask, None, None]:
"""Create and configure Flask app for testing."""
from webapp.src.app import create_app
# Create temporary database file
db_fd, db_path = tempfile.mkstemp(suffix=".db")
os.environ["DATABASE_PATH"] = db_path
# Create app
app = create_app()
app.config["TESTING"] = True
app.config["WTF_CSRF_ENABLED"] = False
# Initialize database schema
with open("webapp/migrations/001_create_tables.sql", "r") as f:
schema = f.read()
conn = sqlite3.connect(db_path)
conn.executescript(schema)
conn.close()
yield app
# Cleanup
os.close(db_fd)
os.unlink(db_path)
@pytest.fixture
def client(app: Flask) -> FlaskClient:
"""Create test client for making requests."""
return app.test_client()
@pytest.fixture
def runner(app: Flask):
"""Create CLI test runner."""
return app.test_cli_runner()
@pytest.fixture
def authenticated_client(client: FlaskClient, monkeypatch) -> FlaskClient:
"""Create authenticated test client with mocked OAuth."""
# Mock OAuth flow
def mock_authorize_redirect(*args, **kwargs):
from flask import redirect
return redirect("/callback?code=test-code")
def mock_fetch_token(*args, **kwargs):
return {"access_token": "test-token", "token_type": "Bearer"}
def mock_fetch_userinfo(*args, **kwargs):
return {
"preferred_username": "testuser",
"name": "Test User",
"picture": "https://example.com/avatar.jpg",
}
# Import and patch auth service
from webapp.src.services.auth_service import auth_service
monkeypatch.setattr(auth_service.hf, "authorize_redirect", mock_authorize_redirect)
monkeypatch.setattr(auth_service, "fetch_token", mock_fetch_token)
monkeypatch.setattr(auth_service, "fetch_userinfo", mock_fetch_userinfo)
# Mock backend API calls
def mock_create_session(*args, **kwargs):
return {
"id": kwargs.get("session_id", "testuser_session"),
"user_id": "testuser",
"created_at": "2025-01-01T00:00:00Z",
}
from webapp.src.services import backend_client
monkeypatch.setattr(
backend_client.backend_client, "create_session", mock_create_session
)
# Perform login flow
with client.session_transaction() as sess:
sess["user_id"] = "testuser"
sess["display_name"] = "Test User"
sess["profile_picture_url"] = "https://example.com/avatar.jpg"
sess["session_id"] = "testuser_session"
sess["access_token"] = "test-token"
return client
@pytest.fixture
def test_user_profile():
"""Create test user profile data."""
return {
"user_id": "testuser",
"display_name": "Test User",
"profile_picture_url": "https://example.com/avatar.jpg",
"session_id": "testuser_session",
"created_at": "2025-01-01T00:00:00Z",
}
@pytest.fixture
def test_contact_session():
"""Create test contact session data."""
return {
"session_id": "testuser_12345678-1234-1234-1234-123456789abc",
"user_id": "testuser",
"display_name": "Alice Smith",
"last_interaction": "2025-01-01T12:00:00Z",
"created_at": "2025-01-01T10:00:00Z",
}
@pytest.fixture
def mock_backend_api(monkeypatch):
"""Mock all backend API calls for testing."""
from webapp.src.services import backend_client
class MockBackendAPI:
"""Mock backend API client."""
def __init__(self):
self.sessions = {}
self.messages = {}
def create_session(self, session_id: str, user_id: str, is_reference: bool = False):
self.sessions[session_id] = {
"id": session_id,
"user_id": user_id,
"is_reference": is_reference,
"created_at": "2025-01-01T00:00:00Z",
}
self.messages[session_id] = []
return self.sessions[session_id]
def get_session(self, session_id: str):
if session_id not in self.sessions:
raise backend_client.BackendAPIError(f"Session {session_id} not found")
return {
**self.sessions[session_id],
"messages": self.messages.get(session_id, []),
}
def send_message(self, session_id: str, content: str, mode: str = "chat", sender: str = "user"):
if session_id not in self.messages:
self.messages[session_id] = []
message = {
"message_id": f"msg_{len(self.messages[session_id])}",
"session_id": session_id,
"mode": mode,
"content": content,
"sender": sender if mode == "chat" else None,
"created_at": "2025-01-01T12:00:00Z",
}
self.messages[session_id].append(message)
return message
def list_sessions(self, user_id: str):
return [s for s in self.sessions.values() if s["user_id"] == user_id]
def get_messages(self, session_id: str, mode: str = None):
messages = self.messages.get(session_id, [])
if mode:
messages = [m for m in messages if m["mode"] == mode]
return messages
mock_api = MockBackendAPI()
monkeypatch.setattr(backend_client, "backend_client", mock_api)
return mock_api