Files
ewoooc/tests/test_webcrumbs_host_data_service.py

117 lines
4.6 KiB
Python

from services import webcrumbs_host_data_service as svc
def test_webcrumbs_host_data_maps_price_alert_exact_rows(monkeypatch):
engine = object()
monkeypatch.setattr(
svc,
"fetch_top_competitor_risks",
lambda passed_engine, limit: [
{
"sku": "SKU-REVIEW",
"name": "需人工覆核的非直接告警候選",
"momo_price": 999,
"pchome_price": 500,
"gap_pct": 99.8,
"match_score": 0.95,
"alert_tier": "identity_review",
"match_type": "exact",
"price_basis": "total_price",
},
{
"sku": "SKU-1",
"name": "Derma Angel 護妍天使 集中抗痘精華",
"momo_price": 420,
"pchome_price": 250,
"gap_pct": 68.0,
"match_score": 0.91,
"alert_tier": "price_alert_exact",
"match_type": "exact",
"price_basis": "total_price",
"pchome_id": "DABC123",
"pchome_name": "Derma Angel 集中抗痘精華",
"crawled_at": "05/31 20:50",
}
],
)
monkeypatch.setattr(
svc,
"fetch_competitor_coverage",
lambda passed_engine: {
"valid_matches": 88,
"match_rate": 12.3,
"fresh_matches": 70,
"fresh_match_rate": 79.5,
"stale_matches": 18,
"pending": 612,
},
)
payload = svc.build_webcrumbs_marketplace_host_data(engine=engine, limit=5)
assert payload["marketSnapshot"][0]["name"].startswith("SKU-1")
assert payload["marketSnapshot"][0]["price"] == 250
assert payload["marketSnapshot"][0]["change_pct"] == 68.0
assert payload["aiCandidate"]["ticker"] == "SKU-1"
assert payload["aiCandidate"]["confidence_score"] == 0.91
assert "MOMO NT$420 vs PChome NT$250" in payload["aiCandidate"]["thesis"]
assert payload["aiCandidate"]["release_status"] == "review_required"
assert payload["metadata"]["writes_database"] is False
assert payload["metadata"]["calls_llm"] is False
assert payload["metadata"]["fetches_external"] is False
assert payload["metadata"]["matched_count"] == 88
assert payload["metadata"]["coverage_rate"] == 12.3
assert payload["metadata"]["fresh_match_count"] == 70
assert payload["metadata"]["fresh_match_rate"] == 79.5
assert payload["metadata"]["stale_match_count"] == 18
assert payload["metadata"]["pending_match_count"] == 612
assert all(row["freshness_status"] == "price_alert_exact" for row in payload["marketSnapshot"])
def test_webcrumbs_host_data_uses_empty_state_without_risks(monkeypatch):
monkeypatch.setattr(svc, "fetch_top_competitor_risks", lambda engine, limit: [])
monkeypatch.setattr(
svc,
"fetch_competitor_coverage",
lambda engine: {"valid_matches": 3, "fresh_matches": 1, "stale_matches": 2, "pending": 9},
)
payload = svc.build_webcrumbs_marketplace_host_data(engine=object(), limit=5)
assert payload["marketSnapshot"][0]["freshness_status"] == "no_current_exact_risk"
assert payload["aiCandidate"]["release_status"] == "blocked"
assert payload["metadata"]["matched_count"] == 3
assert payload["metadata"]["fresh_match_count"] == 1
assert payload["metadata"]["stale_match_count"] == 2
assert payload["metadata"]["pending_match_count"] == 9
assert "非同款、單位價或變體候選" in payload["aiCandidate"]["thesis"]
def test_webcrumbs_seed_data_fallback_does_not_expose_demo_values(monkeypatch):
from services import external_tool_payload_service as payload_service
def boom(limit):
raise RuntimeError("db unavailable")
monkeypatch.setattr(payload_service, "build_webcrumbs_marketplace_host_data", boom)
payload = payload_service.build_webcrumbs_seed_data(limit=5)
assert payload["marketSnapshot"][0]["freshness_status"] == "diagnostic_unavailable"
assert payload["aiCandidate"]["release_status"] == "blocked"
assert "fallback demo" in payload["aiCandidate"]["thesis"]
assert "TAIEX" not in str(payload)
def test_webcrumbs_auth_required_seed_data_is_non_sensitive():
from services.external_tool_payload_service import build_webcrumbs_auth_required_seed_data
payload = build_webcrumbs_auth_required_seed_data()
assert payload["marketSnapshot"][0]["freshness_status"] == "auth_required"
assert payload["aiCandidate"]["release_status"] == "blocked"
assert payload["metadata"]["source"] == "auth_required"
assert "MOMO NT$" not in str(payload)
assert "PChome NT$" not in str(payload)