frimeet-api-nlp / tests /test_api_endpoints.py
AlleksDev's picture
Weight place tags and semantic fields
8595143 unverified
Raw
History Blame Contribute Delete
6.42 kB
from fastapi.testclient import TestClient
from app.main import create_app
def test_places_search_endpoint() -> None:
client = TestClient(create_app())
response = client.post(
"/places/search",
json={
"query": "lugares tranquilos para cenar",
"city": "Tuxtla Gutierrez",
"filters": {"is_active": True},
"limit": 3,
},
)
assert response.status_code == 200
payload = response.json()
assert payload["query"] == "lugares tranquilos para cenar"
assert payload["places"]
assert payload["metrics"]["engine"] == "fasttext_mean_embeddings"
assert payload["metrics"]["candidate_retrieval"] == "mock_embeddings"
assert payload["metrics"]["score_metric"] == "cosine_similarity"
assert payload["metrics"]["ranking_parameters"] == {"dimension": 16.0}
assert payload["metrics"]["field_weights"] == {
"tags": 6,
"category": 4,
"description": 3,
"name": 1,
}
assert payload["metrics"]["returned_count"] == len(payload["places"])
assert payload["metrics"]["max_score"] >= payload["metrics"]["mean_score"]
def test_places_search_metrics_endpoint() -> None:
client = TestClient(create_app())
response = client.get("/places/search/metrics?k=3")
assert response.status_code == 200
payload = response.json()
assert payload["engine"] == "bm25"
assert payload["benchmark"] == "built_in_places_v3_bm25"
assert payload["qrels_source"] == "predefined_graded_qrels"
assert payload["query_count"] == 10
assert payload["metric_definitions"]["precision_at_k"]["label"] == "Precision@3"
assert payload["metric_definitions"]["recall_at_k"]["label"] == "Recall@3"
assert payload["metric_definitions"]["mrr"]["label"] == "MRR"
assert payload["metric_definitions"]["map"]["label"] == "MAP"
assert payload["metric_definitions"]["ndcg_at_k"]["label"] == "nDCG@3"
assert payload["recommended_metric"]["key"] == "ndcg_at_k"
assert payload["recommended_metric"]["label"] == "nDCG@3"
assert payload["recommended_metric"]["value"] == payload["aggregate"]["ndcg_at_k"]
assert all(
0.0 <= payload["aggregate"][metric] <= 1.0
for metric in ["precision_at_k", "recall_at_k", "mrr", "map", "ndcg_at_k"]
)
def test_places_search_metrics_post_requires_no_body() -> None:
client = TestClient(create_app())
response = client.post("/places/search/metrics?k=2")
assert response.status_code == 200
payload = response.json()
assert payload["k"] == 2
assert payload["query_count"] == 10
def test_places_chat_endpoint_returns_trace_and_structured_places() -> None:
client = TestClient(create_app())
response = client.post(
"/places/chat",
json={
"message": "quiero una cena tranquila con mi pareja",
"city": "Tuxtla Gutierrez",
"filters": {"occasion": "pareja", "is_active": True},
"limit": 3,
},
)
assert response.status_code == 200
payload = response.json()
assert payload["response_id"].startswith("resp_")
assert payload["nlp_trace_id"].startswith("trace_")
assert payload["message"]
assert payload["places"]
assert payload["metadata"]["places_used_as_context"]
def test_places_recommendations_returns_llm_message_and_semantic_metadata() -> None:
client = TestClient(create_app())
response = client.post(
"/places/recommendations",
json={
"query": "quiero ver el atardecer y tomar fotos",
"city": "Tuxtla Gutierrez",
"filters": {"is_active": True},
"limit": 3,
},
)
assert response.status_code == 200
payload = response.json()
assert payload["message"]
assert payload["places"]
assert payload["metrics"]["engine"] == "fasttext_mean_embeddings"
assert payload["metrics"]["score_metric"] == "cosine_similarity"
assert payload["metrics"]["returned_count"] == len(payload["places"])
assert payload["metrics"]["candidate_retrieval"] == "mock_embeddings"
assert payload["metrics"]["query_token_count"] > 0
assert payload["metrics"]["matched_query_token_count"] > 0
assert payload["metrics"]["scope"] == "current_query"
assert payload["metrics"]["ground_truth_available"] is False
assert "evaluation_metrics" not in payload
assert payload["metadata"]["ranking"] == "fasttext_mean_embeddings"
assert payload["metadata"]["response_mode"] == "confident"
assert payload["metadata"]["used_llm"] is True
def test_places_recommendations_returns_no_places_without_candidates() -> None:
client = TestClient(create_app())
response = client.post(
"/places/recommendations",
json={
"query": "xqzv blorf 998zz",
"city": "Ciudad inexistente",
"filters": {"is_active": True},
"limit": 3,
},
)
assert response.status_code == 200
payload = response.json()
assert payload["places"] == []
assert payload["metrics"]["max_score"] == 0.0
assert payload["metrics"]["returned_count"] == 0
assert payload["metrics"]["match_quality"] == "no_match"
assert payload["metadata"]["response_mode"] == "no_match"
assert payload["message"]
def test_places_search_rejects_incomplete_coordinates() -> None:
client = TestClient(create_app())
response = client.post(
"/places/search",
json={
"query": "parque cercano",
"lat": 16.7531,
"limit": 5,
},
)
assert response.status_code == 422
def test_posts_recommendations_endpoint() -> None:
client = TestClient(create_app())
response = client.post(
"/posts/recommendations",
json={
"query": "ideas para fotos con amigos",
"city": "Tuxtla Gutierrez",
"limit": 3,
},
)
assert response.status_code == 200
payload = response.json()
assert payload["posts"]
assert payload["metadata"]["computed_clusters_during_request"] is False
def test_posts_clusters_endpoint() -> None:
client = TestClient(create_app())
response = client.get("/posts/clusters")
assert response.status_code == 200
payload = response.json()
assert payload["clusters"]
assert payload["metadata"]["computed_during_request"] is False