Advisor-test / tests /test_e2e.py
ps1811's picture
initial push
fcda9b0
Raw
History Blame Contribute Delete
3 kB
import pytest
from unittest.mock import patch
from app.recs.rules import generate_recommendations
from app.recs.generate import generate_explanation
from app.db.repo import init_db, SessionLocal
from app.db.models import Campaign, Recommendation
# -------------------------
# DB fixture
# -------------------------
@pytest.fixture
def session():
init_db()
db = SessionLocal()
yield db
db.close()
# -------------------------
# Step 1: seed campaigns (DB → metrics extraction simulation)
# -------------------------
def seed_campaign_metrics(session):
campaigns = [
Campaign(
google_campaign_id="c1",
name="High CPL Campaign",
budget=100,
spend=500,
clicks=100,
impressions=2000,
ctr=5.0,
leads=5,
cpl=100.0,
),
Campaign(
google_campaign_id="c2",
name="Low CPL Campaign",
budget=100,
spend=200,
clicks=150,
impressions=3000,
ctr=5.0,
leads=20,
cpl=10.0,
),
Campaign(
google_campaign_id="c3",
name="Low CTR Campaign",
budget=100,
spend=300,
clicks=20,
impressions=3000,
ctr=1.0,
leads=5,
cpl=60.0,
),
]
session.add_all(campaigns)
session.commit()
return campaigns
# -------------------------
# Convert DB → rule engine input format
# -------------------------
def extract_metrics(session):
campaigns = session.query(Campaign).all()
return [
{
"campaign_id": c.google_campaign_id,
"cpl": c.cpl,
"ctr": c.ctr,
}
for c in campaigns
]
# -------------------------
# E2E TEST
# -------------------------
def test_e2e_pipeline(session):
# STEP 1: seed DB
seed_campaign_metrics(session)
metrics = extract_metrics(session)
# STEP 2: rule engine
recs = generate_recommendations(metrics)
assert len(recs) > 0, "Rule engine returned no recommendations"
# (Optional sanity check)
assert any(r["type"] == "high_cpl" for r in recs)
assert any(r["type"] == "low_ctr" for r in recs)
# STEP 3: mock LLM (MiniCPM)
def fake_llm_response(rec):
return f"Mock explanation for {rec['campaign_id']}"
with patch("app.recs.generate.load_model", return_value=None), \
patch("app.recs.generate.generate_explanation") as mocked:
mocked.side_effect = fake_llm_response
enriched = [
{
**r,
"explanation": generate_explanation(r)
}
for r in recs
]
# STEP 4: verify enrichment
assert len(enriched) == len(recs)
for e in enriched:
assert "explanation" in e
assert e["explanation"] is not None
assert isinstance(e["explanation"], str)