218 lines
6.4 KiB
Python
218 lines
6.4 KiB
Python
import uuid
|
|
|
|
|
|
def test_create_minimal(client, product_data):
|
|
r = client.post("/products", json=product_data)
|
|
assert r.status_code == 201
|
|
data = r.json()
|
|
assert "id" in data
|
|
assert data["name"] == product_data["name"]
|
|
assert data["brand"] == product_data["brand"]
|
|
assert data["category"] == "moisturizer"
|
|
|
|
|
|
def test_create_with_actives(client, product_data):
|
|
product_data["actives"] = [
|
|
{"name": "Niacinamide", "percent": 10.0, "functions": ["niacinamide"]}
|
|
]
|
|
r = client.post("/products", json=product_data)
|
|
assert r.status_code == 201
|
|
data = r.json()
|
|
assert len(data["actives"]) == 1
|
|
assert data["actives"][0]["name"] == "Niacinamide"
|
|
assert data["actives"][0]["percent"] == 10.0
|
|
|
|
|
|
def test_create_invalid_enum(client, product_data):
|
|
product_data["category"] = "not_a_category"
|
|
r = client.post("/products", json=product_data)
|
|
assert r.status_code == 422
|
|
|
|
|
|
def test_create_missing_required(client, product_data):
|
|
del product_data["name"]
|
|
r = client.post("/products", json=product_data)
|
|
assert r.status_code == 422
|
|
|
|
|
|
def test_list_empty(client):
|
|
r = client.get("/products")
|
|
assert r.status_code == 200
|
|
assert r.json() == []
|
|
|
|
|
|
def test_list_returns_created(client, created_product):
|
|
r = client.get("/products")
|
|
assert r.status_code == 200
|
|
ids = [p["id"] for p in r.json()]
|
|
assert created_product["id"] in ids
|
|
|
|
|
|
def test_list_filter_category(client, client_and_data=None):
|
|
# Create a moisturizer and a serum
|
|
base = {
|
|
"brand": "B",
|
|
"recommended_time": "both",
|
|
"leave_on": True,
|
|
}
|
|
r1 = client.post(
|
|
"/products", json={**base, "name": "Moist", "category": "moisturizer"}
|
|
)
|
|
r2 = client.post("/products", json={**base, "name": "Ser", "category": "serum"})
|
|
assert r1.status_code == 201
|
|
assert r2.status_code == 201
|
|
|
|
r = client.get("/products?category=moisturizer")
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert all(p["category"] == "moisturizer" for p in data)
|
|
names = [p["name"] for p in data]
|
|
assert "Moist" in names
|
|
assert "Ser" not in names
|
|
|
|
|
|
def test_list_filter_brand(client):
|
|
base = {
|
|
"recommended_time": "both",
|
|
"leave_on": True,
|
|
"category": "serum",
|
|
}
|
|
client.post("/products", json={**base, "name": "A1", "brand": "BrandA"})
|
|
client.post("/products", json={**base, "name": "B1", "brand": "BrandB"})
|
|
|
|
r = client.get("/products?brand=BrandA")
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert all(p["brand"] == "BrandA" for p in data)
|
|
assert len(data) == 1
|
|
|
|
|
|
def test_list_filter_is_medication(client):
|
|
base = {
|
|
"brand": "B",
|
|
"recommended_time": "both",
|
|
"leave_on": True,
|
|
"category": "serum",
|
|
}
|
|
client.post("/products", json={**base, "name": "Normal", "is_medication": False})
|
|
client.post(
|
|
"/products",
|
|
json={
|
|
**base,
|
|
"name": "Med",
|
|
"is_medication": True,
|
|
},
|
|
)
|
|
|
|
r = client.get("/products?is_medication=true")
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert all(p["is_medication"] is True for p in data)
|
|
assert len(data) == 1
|
|
assert data[0]["name"] == "Med"
|
|
|
|
|
|
def test_list_filter_targets(client):
|
|
base = {
|
|
"brand": "B",
|
|
"recommended_time": "both",
|
|
"leave_on": True,
|
|
"category": "serum",
|
|
}
|
|
client.post("/products", json={**base, "name": "Acne", "targets": ["acne"]})
|
|
client.post("/products", json={**base, "name": "Aging", "targets": ["aging"]})
|
|
|
|
r = client.get("/products?targets=acne")
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert len(data) == 1
|
|
assert data[0]["name"] == "Acne"
|
|
|
|
|
|
def test_get_by_id(client, created_product):
|
|
pid = created_product["id"]
|
|
r = client.get(f"/products/{pid}")
|
|
assert r.status_code == 200
|
|
assert r.json()["id"] == pid
|
|
|
|
|
|
def test_get_not_found(client):
|
|
r = client.get(f"/products/{uuid.uuid4()}")
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_update_name(client, created_product):
|
|
pid = created_product["id"]
|
|
r = client.patch(f"/products/{pid}", json={"name": "New Name"})
|
|
assert r.status_code == 200
|
|
assert r.json()["name"] == "New Name"
|
|
|
|
|
|
def test_update_json_field(client, created_product):
|
|
pid = created_product["id"]
|
|
r = client.patch(f"/products/{pid}", json={"inci": ["Water", "Glycerin"]})
|
|
assert r.status_code == 200
|
|
assert r.json()["inci"] == ["Water", "Glycerin"]
|
|
|
|
|
|
def test_update_not_found(client):
|
|
r = client.patch(f"/products/{uuid.uuid4()}", json={"name": "x"})
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_delete(client, created_product):
|
|
pid = created_product["id"]
|
|
r = client.delete(f"/products/{pid}")
|
|
assert r.status_code == 204
|
|
r2 = client.get(f"/products/{pid}")
|
|
assert r2.status_code == 404
|
|
|
|
|
|
def test_delete_not_found(client):
|
|
r = client.delete(f"/products/{uuid.uuid4()}")
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_list_inventory_empty(client, created_product):
|
|
pid = created_product["id"]
|
|
r = client.get(f"/products/{pid}/inventory")
|
|
assert r.status_code == 200
|
|
assert r.json() == []
|
|
|
|
|
|
def test_list_inventory_product_not_found(client):
|
|
r = client.get(f"/products/{uuid.uuid4()}/inventory")
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_create_inventory(client, created_product):
|
|
pid = created_product["id"]
|
|
r = client.post(f"/products/{pid}/inventory", json={"is_opened": False})
|
|
assert r.status_code == 201
|
|
data = r.json()
|
|
assert data["product_id"] == pid
|
|
assert data["is_opened"] is False
|
|
|
|
|
|
def test_create_inventory_product_not_found(client):
|
|
r = client.post(f"/products/{uuid.uuid4()}/inventory", json={})
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_parse_text_accepts_numeric_strength_levels(client, monkeypatch):
|
|
from innercontext.api import products as products_api
|
|
|
|
class _FakeResponse:
|
|
text = (
|
|
'{"name":"Test Serum","actives":[{"name":"Niacinamide","percent":10,'
|
|
'"functions":["niacinamide"],"strength_level":2,"irritation_potential":1}]}'
|
|
)
|
|
|
|
monkeypatch.setattr(products_api, "call_gemini", lambda **kwargs: _FakeResponse())
|
|
|
|
r = client.post("/products/parse-text", json={"text": "dummy input"})
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["name"] == "Test Serum"
|
|
assert data["actives"][0]["strength_level"] == 2
|
|
assert data["actives"][0]["irritation_potential"] == 1
|