File size: 4,024 Bytes
d992912 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | from unittest.mock import MagicMock
import pandas as pd
from fastapi.testclient import TestClient
from backend.app.main import app
def _make_search_results():
df = pd.DataFrame([{
"sku": "12345",
"name": "Test Dress",
"brand": "ASOS",
"price": 29.99,
"color_clean": "black",
"color_family": "black",
"category": "Dresses",
"gender": "Women",
"primary_image_url": "https://example.com/img.jpg",
"hybrid_score": 0.95,
"style_tags": ["casual"],
"any_in_stock": True,
}])
df.attrs["query_info"] = {
"original_query": "black dress",
"processed_query": "black dress",
"detected_language": "en",
"was_translated": False,
"was_spell_corrected": False,
"spell_suggestion": None,
"parsed_category": "Dresses",
"parsed_color": "black",
"parsed_price_range": [None, None],
"parsed_gender": None,
"parsed_style_tags": [],
"parsed_material": None,
"parsed_size": None,
"parsed_exclusions": [],
"sort_by": "relevance",
"available_sorts": ["relevance", "price_asc", "price_desc"],
"suggested_searches": ["navy dresses"],
}
return df
def _make_mock_engine():
engine = MagicMock()
engine._is_ready = True
engine.search.return_value = _make_search_results()
return engine
class TestSearchEndpoints:
def test_text_search(self):
app.state.engine = _make_mock_engine()
client = TestClient(app, raise_server_exceptions=False)
response = client.post("/api/v1/search", json={"query": "black dress"})
assert response.status_code == 200
data = response.json()
assert data["total"] == 1
assert data["results"][0]["sku"] == "12345"
assert data["results"][0]["name"] == "Test Dress"
assert data["query_info"]["parsed_category"] == "Dresses"
def test_search_with_params(self):
app.state.engine = _make_mock_engine()
client = TestClient(app, raise_server_exceptions=False)
response = client.post("/api/v1/search", json={
"query": "red shoes",
"top_n": 5,
"sort_by": "price_asc",
})
assert response.status_code == 200
def test_empty_query_rejected(self):
app.state.engine = _make_mock_engine()
client = TestClient(app, raise_server_exceptions=False)
response = client.post("/api/v1/search", json={"query": ""})
assert response.status_code == 422
def test_engine_not_ready(self):
app.state.engine = None
client = TestClient(app, raise_server_exceptions=False)
response = client.post("/api/v1/search", json={"query": "dress"})
assert response.status_code == 503
def test_similar_search(self):
engine = _make_mock_engine()
engine.get_product_detail.return_value = {
"sku": "12345", "name": "Test Dress", "brand": "ASOS",
"price": 29.99, "color_clean": "black", "color_family": "black",
"category": "Dresses", "gender": "Women",
"primary_image_url": "https://example.com/img.jpg",
"image_urls": [], "style_tags": [], "materials": [],
"sizes_available": [], "product_details": "", "any_in_stock": True,
}
engine.search_similar.return_value = pd.DataFrame([{
"sku": "67890", "name": "Similar Dress", "brand": "ASOS",
"price": 35.00, "color_clean": "navy", "category": "Dresses",
"primary_image_url": "https://example.com/img2.jpg",
"similarity_score": 0.89,
}])
app.state.engine = engine
client = TestClient(app, raise_server_exceptions=False)
response = client.get("/api/v1/search/similar/12345")
assert response.status_code == 200
data = response.json()
assert data["total"] == 1
assert data["results"][0]["similarity_score"] == 0.89
|