119 lines
3.9 KiB
Python
119 lines
3.9 KiB
Python
from __future__ import annotations
|
||
|
||
from fastapi.testclient import TestClient
|
||
|
||
from app.main import app, create_app
|
||
|
||
client = TestClient(app)
|
||
|
||
|
||
def test_service_exposes_only_match_endpoint() -> None:
|
||
application_paths = [route.path for route in app.routes]
|
||
assert application_paths == ["/match"]
|
||
|
||
|
||
def test_match_contract_and_message_order() -> None:
|
||
messages = [
|
||
"бур sds 10х210",
|
||
"где находится ваш магазин",
|
||
"нужен кабель",
|
||
]
|
||
response = client.post("/match", json={"messages": messages})
|
||
assert response.status_code == 200
|
||
|
||
body = response.json()
|
||
assert set(body) == {"results"}
|
||
assert [result["message"] for result in body["results"]] == messages
|
||
assert [result["status"] for result in body["results"]] == [
|
||
"matched",
|
||
"not_found",
|
||
"ambiguous",
|
||
]
|
||
|
||
for result in body["results"]:
|
||
assert set(result) == {"message", "status", "candidates"}
|
||
assert len(result["candidates"]) <= 3
|
||
for candidate in result["candidates"]:
|
||
assert set(candidate) == {"sku", "confidence"}
|
||
assert 0.0 <= candidate["confidence"] <= 1.0
|
||
|
||
|
||
def test_task_example_uses_required_request_and_response_shape() -> None:
|
||
message = "саморезы по дереву 4.2 на 75, пачку"
|
||
response = client.post("/match", json={"messages": [message]})
|
||
|
||
assert response.status_code == 200
|
||
body = response.json()
|
||
assert set(body) == {"results"}
|
||
assert len(body["results"]) == 1
|
||
|
||
result = body["results"][0]
|
||
assert set(result) == {"message", "status", "candidates"}
|
||
assert result["message"] == message
|
||
assert result["status"] in {"matched", "ambiguous", "not_found"}
|
||
for candidate in result["candidates"]:
|
||
assert set(candidate) == {"sku", "confidence"}
|
||
assert isinstance(candidate["sku"], str)
|
||
assert isinstance(candidate["confidence"], float)
|
||
|
||
|
||
def test_empty_message_list_is_valid() -> None:
|
||
response = client.post("/match", json={"messages": []})
|
||
assert response.status_code == 200
|
||
assert response.json() == {"results": []}
|
||
|
||
|
||
def test_messages_field_is_required() -> None:
|
||
response = client.post("/match", json={})
|
||
|
||
assert response.status_code == 422
|
||
|
||
|
||
def test_unknown_request_fields_are_rejected() -> None:
|
||
response = client.post("/match", json={"messages": [], "debug": True})
|
||
assert response.status_code == 422
|
||
|
||
|
||
def test_opt_in_info_route_returns_catalog_item() -> None:
|
||
test_app = create_app(enable_test_info_route=True)
|
||
test_client = TestClient(test_app)
|
||
|
||
assert [route.path for route in test_app.routes] == [
|
||
"/match",
|
||
"/get_info_by/{sku}",
|
||
]
|
||
|
||
response = test_client.get("/get_info_by/bit-0073")
|
||
assert response.status_code == 200
|
||
assert set(response.json()) == {"sku", "name", "unit", "price"}
|
||
assert response.json()["sku"] == "BIT-0073"
|
||
assert response.json()["name"]
|
||
assert response.json()["unit"]
|
||
assert float(response.json()["price"]) > 0
|
||
|
||
|
||
def test_opt_in_info_route_returns_404_for_unknown_sku() -> None:
|
||
test_client = TestClient(create_app(enable_test_info_route=True))
|
||
|
||
response = test_client.get("/get_info_by/UNKNOWN-0000")
|
||
|
||
assert response.status_code == 404
|
||
assert response.json() == {"detail": "SKU not found"}
|
||
|
||
|
||
def test_opt_in_routes_allow_requests_from_local_html_page() -> None:
|
||
test_client = TestClient(create_app(enable_test_info_route=True))
|
||
response = test_client.options(
|
||
"/match",
|
||
headers={
|
||
"Origin": "null",
|
||
"Access-Control-Request-Method": "POST",
|
||
"Access-Control-Request-Headers": "content-type",
|
||
},
|
||
)
|
||
|
||
assert response.status_code == 200
|
||
assert response.headers["access-control-allow-origin"] == "*"
|
||
assert "POST" in response.headers["access-control-allow-methods"]
|
||
assert "GET" in response.headers["access-control-allow-methods"]
|