techprotrade's picture
Deploy ATOM FastAPI command center runtime (part 7)
cc036ff verified
Raw
History Blame Contribute Delete
12.1 kB
"""
API-first fixtures for fast test initialization.
This module provides pytest fixtures that use API calls to quickly set up
test data, bypassing slow UI navigation (10-100x speedup).
"""
import pytest
from typing import Dict, Any
from sqlalchemy.orm import Session
from tests.e2e_ui.utils.api_setup import (
APIClient,
create_test_user,
authenticate_user,
get_test_user_token,
create_test_project,
install_test_skill
)
# ============================================================================
# Base Fixtures
# ============================================================================
@pytest.fixture(scope="session")
def api_base_url() -> str:
"""
Get the base URL for API requests.
Returns:
Base URL (default: http://localhost:8001)
"""
return "http://localhost:8001"
@pytest.fixture(scope="function")
def api_client(api_base_url: str) -> APIClient:
"""
Provide an API client instance for making HTTP requests.
Args:
api_base_url: Base URL for API requests
Returns:
APIClient instance
"""
return APIClient(base_url=api_base_url)
# ============================================================================
# User Fixtures
# ============================================================================
@pytest.fixture(scope="function")
def test_user_data() -> Dict[str, str]:
"""
Provide test user data for creating a user.
Returns:
Dictionary with user email, password, first_name, last_name
"""
import uuid
unique_id = str(uuid.uuid4())[:8]
return {
"email": f"test-{unique_id}@example.com",
"password": "TestPassword123!",
"first_name": "Test",
"last_name": f"User{unique_id}"
}
@pytest.fixture(scope="function")
def setup_test_user(api_client: APIClient, test_user_data: Dict[str, str]) -> Dict[str, Any]:
"""
Create a test user via API and return user data with token.
This fixture bypasses UI login for 10-100x speedup.
Args:
api_client: APIClient instance
test_user_data: User data dictionary
Returns:
Dictionary with user data and access_token
Example:
def test_example(setup_test_user):
user = setup_test_user["user"]
token = setup_test_user["access_token"]
"""
# Create user via API
user_response = create_test_user(
client=api_client,
email=test_user_data["email"],
password=test_user_data["password"],
first_name=test_user_data["first_name"],
last_name=test_user_data["last_name"]
)
# Authenticate and get token
token = get_test_user_token(
client=api_client,
email=test_user_data["email"],
password=test_user_data["password"]
)
return {
"user": user_response.get("user", user_response),
"access_token": token,
"email": test_user_data["email"],
"password": test_user_data["password"]
}
@pytest.fixture(scope="function")
def authenticated_api_client(api_client: APIClient, setup_test_user: Dict[str, Any]) -> APIClient:
"""
Provide an API client with authentication token already set.
Args:
api_client: APIClient instance
setup_test_user: User data with access_token
Returns:
APIClient instance with token set
"""
token = setup_test_user["access_token"]
api_client.set_token(token)
return api_client
# ============================================================================
# Project Fixtures
# ============================================================================
@pytest.fixture(scope="function")
def test_project_data() -> Dict[str, str]:
"""
Provide test project data.
Returns:
Dictionary with project name and description
"""
import uuid
unique_id = str(uuid.uuid4())[:8]
return {
"name": f"Test Project {unique_id}",
"description": f"Test project description {unique_id}"
}
@pytest.fixture(scope="function")
def setup_test_project(authenticated_api_client: APIClient, test_project_data: Dict[str, str]) -> Dict[str, Any]:
"""
Create a test project via API and return project data.
Args:
authenticated_api_client: Authenticated APIClient instance
test_project_data: Project data dictionary
Returns:
Project data response from API
Example:
def test_example(setup_test_project):
project = setup_test_project["project"]
project_id = project["id"]
"""
response = create_test_project(
client=authenticated_api_client,
name=test_project_data["name"],
description=test_project_data["description"]
)
return {
"project": response.get("project", response),
"name": test_project_data["name"],
"description": test_project_data["description"]
}
# ============================================================================
# Skill Fixtures
# ============================================================================
@pytest.fixture(scope="function")
def test_skill_data() -> Dict[str, str]:
"""
Provide test skill data.
Returns:
Dictionary with skill_id and agent_id
"""
return {
"skill_id": "test-skill-001",
"agent_id": "test-agent-001"
}
@pytest.fixture(scope="function")
def setup_test_skill(authenticated_api_client: APIClient, test_skill_data: Dict[str, str]) -> Dict[str, Any]:
"""
Install a test skill via API and return skill data.
Args:
authenticated_api_client: Authenticated APIClient instance
test_skill_data: Skill data dictionary
Returns:
Skill installation response from API
Example:
def test_example(setup_test_skill):
result = setup_test_skill["result"]
skill_id = result.get("skill_id")
"""
response = install_test_skill(
client=authenticated_api_client,
skill_id=test_skill_data["skill_id"],
agent_id=test_skill_data["agent_id"]
)
return {
"result": response,
"skill_id": test_skill_data["skill_id"],
"agent_id": test_skill_data["agent_id"]
}
# ============================================================================
# Agent Fixtures
# ============================================================================
@pytest.fixture(scope="function")
def test_agent_data() -> Dict[str, str]:
"""
Provide test agent data for creating agents.
Returns:
Dictionary with agent_id, name, status (STUDENT/INTERN/SUPERVISED/AUTONOMOUS)
Example:
def test_example(test_agent_data):
agent_id = test_agent_data["agent_id"]
status = test_agent_data["status"]
"""
import uuid
unique_id = str(uuid.uuid4())[:8]
return {
"agent_id": f"test-agent-{unique_id}",
"name": f"Test Agent {unique_id}",
"category": "testing",
"module_path": "backend/test_agents",
"class_name": "TestAgent",
"description": f"Test agent for E2E testing {unique_id}",
"status": "STUDENT" # Default to STUDENT maturity
}
@pytest.fixture(scope="function")
def setup_test_agent(test_agent_data: Dict[str, str]) -> Dict[str, Any]:
"""
Create a test agent via database and return agent data.
This fixture bypasses UI agent creation for 10-100x speedup.
Uses direct database access via db_session fixture.
Args:
test_agent_data: Agent data dictionary
Returns:
Dictionary with agent data including agent_id, name, status
Example:
def test_example(setup_test_agent):
agent = setup_test_agent["agent"]
agent_id = setup_test_agent["agent_id"]
"""
import sys
import os
# Add backend to path for imports
backend_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
if backend_dir not in sys.path:
sys.path.insert(0, backend_dir)
from core.models import AgentRegistry, AgentStatus
from sqlalchemy.orm import Session
# Import db_session fixture - we need to use pytest's request fixture
# to get the db_session dynamically
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# Get database URL from environment
database_url = os.getenv(
"DATABASE_URL",
"postgresql://atom:atom_test@localhost:5432/atom_test"
)
# Create engine and session
engine = create_engine(database_url, pool_pre_ping=True)
Session = sessionmaker(bind=engine)
db = Session()
try:
# Create agent directly in database
agent = AgentRegistry(
name=test_agent_data["name"],
category=test_agent_data["category"],
module_path=test_agent_data["module_path"],
class_name=test_agent_data["class_name"],
description=test_agent_data["description"],
status=AgentStatus[test_agent_data["status"].upper()].value,
confidence_score=0.5 # Default confidence score
)
db.add(agent)
db.commit()
db.refresh(agent)
return {
"agent": agent,
"agent_id": str(agent.id),
"name": agent.name,
"status": agent.status,
"category": agent.category
}
finally:
db.close()
def create_test_agent_direct(db: Session, name: str, status: str, category: str = "testing", confidence_score: float = 0.5) -> Dict[str, Any]:
"""
Helper function to create an agent with specified maturity level directly in database.
This is a convenience function for inline agent creation in tests.
Uses direct database session for fast agent creation without API calls.
Args:
db: SQLAlchemy database session
name: Agent name
status: Agent maturity level (STUDENT, INTERN, SUPERVISED, AUTONOMOUS)
category: Agent category (default: "testing")
confidence_score: Agent confidence score (default: 0.5)
Returns:
Dictionary with agent_id and confirmation
Example:
agent = create_test_agent_direct(db, "My Student Agent", "STUDENT")
agent_id = agent["agent_id"]
"""
import uuid
from core.models import AgentRegistry, AgentStatus
unique_id = str(uuid.uuid4())[:8]
# Create agent directly in database
agent = AgentRegistry(
name=name,
category=category,
module_path="backend/test_agents",
class_name="TestAgent",
description=f"Test agent {name}",
status=AgentStatus[status.upper()].value,
confidence_score=confidence_score
)
db.add(agent)
db.commit()
db.refresh(agent)
return {
"agent_id": str(agent.id),
"agent": agent,
"name": name,
"status": status,
"category": category,
"success": True
}
# ============================================================================
# Combined Fixtures
# ============================================================================
@pytest.fixture(scope="function")
def setup_full_test_state(
authenticated_api_client: APIClient,
setup_test_project: Dict[str, Any],
setup_test_skill: Dict[str, Any]
) -> Dict[str, Any]:
"""
Set up complete test state with user, project, and skill.
This fixture provides a fully initialized test state without any UI navigation.
Args:
authenticated_api_client: Authenticated APIClient instance
setup_test_project: Project data
setup_test_skill: Skill data
Returns:
Dictionary with all test data
Example:
def test_example(setup_full_test_state):
project = setup_full_test_state["project"]
skill = setup_full_test_state["skill"]
"""
return {
"project": setup_test_project["project"],
"skill": setup_test_skill["result"],
"client": authenticated_api_client
}