amo-server/tests/test_api.py

254 lines
7.0 KiB
Python

"""
Test API endpoints with AMO CRM data examples
"""
import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool
from app import app
from adapters.sqlite.database import Base, get_db
from tests.fixtures.amocrm_responses import USERS_RESPONSE, DEALS_RESPONSE
# Create test database
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL,
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# Create tables
Base.metadata.create_all(bind=engine)
def override_get_db():
try:
db = TestingSessionLocal()
yield db
finally:
db.close()
app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)
def test_root_endpoint():
"""Test root endpoint"""
response = client.get("/")
assert response.status_code == 200
data = response.json()
assert data["message"] == "AMO CRM Data Collection Service"
assert data["version"] == "0.1.0"
def test_health_endpoint():
"""Test health check endpoint"""
response = client.get("/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "healthy"
def test_list_entities_empty():
"""Test listing entities when database is empty"""
response = client.get("/api/v1/entities/")
assert response.status_code == 200
data = response.json()
assert "entities" in data
# All counts should be 0
for entity_type in ["deals", "contacts", "companies", "pipelines", "users", "events"]:
assert entity_type in data["entities"]
assert data["entities"][entity_type]["count"] == 0
def test_put_users_data():
"""Test putting users data"""
users_data = USERS_RESPONSE["_embedded"]["users"]
response = client.post(
"/api/v1/data/users",
json={
"data": users_data,
"sync_mode": "upsert"
}
)
assert response.status_code == 200
data = response.json()
assert data["processed_count"] == 2
assert "Processed 2 users" in data["message"]
def test_put_deals_data():
"""Test putting deals data"""
deals_data = DEALS_RESPONSE["_embedded"]["leads"]
response = client.post(
"/api/v1/data/deals",
json={
"data": deals_data,
"sync_mode": "upsert"
}
)
assert response.status_code == 200
data = response.json()
assert data["processed_count"] == 2
assert "Processed 2 deals" in data["message"]
def test_list_entities_with_data():
"""Test listing entities after adding data"""
response = client.get("/api/v1/entities/")
assert response.status_code == 200
data = response.json()
# Should have users and deals now
assert data["entities"]["users"]["count"] == 2
assert data["entities"]["deals"]["count"] == 2
def test_list_deal_fields():
"""Test listing deal fields"""
response = client.get("/api/v1/entities/deals/fields")
assert response.status_code == 200
data = response.json()
assert data["entity_type"] == "deals"
assert "fields" in data
# Should have standard fields
field_names = [f["name"] for f in data["fields"]]
assert "name" in field_names
assert "price" in field_names
assert "created_at" in field_names
# Should have custom fields from the test data
custom_fields = [f for f in data["fields"] if f["is_custom"]]
assert len(custom_fields) > 0
def test_export_configuration():
"""Test creating export configuration"""
config_data = {
"name": "Test Export Configuration",
"sheet_id": "test-sheet-id-123",
"date_range_start": "2024-01-01T00:00:00Z",
"date_range_end": "2024-12-31T23:59:59Z",
"entity_mappings": {
"deals": {
"sheet_name": "Deals",
"is_enabled": True,
"field_mapping": [
{"field_name": "name", "column": "A", "order": 1},
{"field_name": "price", "column": "B", "order": 2}
]
},
"users": {
"sheet_name": "Users",
"is_enabled": True,
"field_mapping": [
{"field_name": "name", "column": "A", "order": 1},
{"field_name": "email", "column": "B", "order": 2}
]
}
}
}
response = client.post("/api/v1/export/configure", json=config_data)
assert response.status_code == 200
data = response.json()
assert "configuration_id" in data
assert data["message"] == "Export configuration created successfully"
return data["configuration_id"]
def test_list_export_configurations():
"""Test listing export configurations"""
# First create a configuration
config_id = test_export_configuration()
response = client.get("/api/v1/export/configurations")
assert response.status_code == 200
data = response.json()
assert "configurations" in data
assert len(data["configurations"]) >= 1
config = data["configurations"][0]
assert config["name"] == "Test Export Configuration"
assert config["sheet_id"] == "test-sheet-id-123"
assert "entity_mappings" in config
def test_start_export_job():
"""Test starting export job"""
# First create a configuration
config_id = test_export_configuration()
response = client.post(
"/api/v1/export/start",
json={"configuration_id": config_id}
)
assert response.status_code == 200
data = response.json()
assert "job_id" in data
assert data["status"] == "pending"
assert data["message"] == "Export job queued successfully"
return data["job_id"]
def test_export_job_status():
"""Test getting export job status"""
# First start a job
job_id = test_start_export_job()
response = client.get(f"/api/v1/export/status/{job_id}")
assert response.status_code == 200
data = response.json()
assert data["job_id"] == job_id
assert data["status"] == "pending"
assert "progress" in data
assert data["progress"]["records_processed"] == 0
def test_list_export_jobs():
"""Test listing export jobs"""
# First start a job
job_id = test_start_export_job()
response = client.get("/api/v1/export/jobs")
assert response.status_code == 200
data = response.json()
assert "jobs" in data
assert data["total"] >= 1
assert data["page"] == 1
assert data["per_page"] == 20
# Should contain our job
job_ids = [job["job_id"] for job in data["jobs"]]
assert job_id in job_ids
def test_invalid_entity_type():
"""Test invalid entity type"""
response = client.get("/api/v1/entities/invalid_entity/fields")
assert response.status_code == 404
data = response.json()
assert "Entity type not found" in data["detail"]
if __name__ == "__main__":
pytest.main([__file__])