Updated backend
This commit is contained in:
@@ -13,29 +13,13 @@ automatically unless `RUN_INTEGRATION_TESTS=1` is set - see that file).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
# Make sure required-but-not-secret-critical settings have *something* set
|
||||
# before app.main is imported, so settings.py's _require() checks don't
|
||||
# blow up the test run when no real .env is present.
|
||||
os.environ.setdefault("USE_PGVECTOR", "true")
|
||||
os.environ.setdefault("DB_PASSWORD", "test-password-not-real")
|
||||
os.environ.setdefault("USE_S3", "false")
|
||||
os.environ.setdefault("USE_GOOGLE_CSE", "false")
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from app.main import app
|
||||
|
||||
client = TestClient(app)
|
||||
# Environment setup (settings that must exist before app.main is imported,
|
||||
# including the auth secrets) lives in tests/conftest.py, which pytest loads
|
||||
# first. The `client`, `admin_headers` and `user_headers` fixtures come from
|
||||
# there too.
|
||||
|
||||
|
||||
def test_root() -> None:
|
||||
def test_root(client) -> None:
|
||||
resp = client.get("/")
|
||||
assert resp.status_code == 200
|
||||
if "text/html" in resp.headers.get("content-type", ""):
|
||||
@@ -44,7 +28,7 @@ def test_root() -> None:
|
||||
assert "service" in resp.json()
|
||||
|
||||
|
||||
def test_health_degrades_gracefully_without_dependencies() -> None:
|
||||
def test_health_degrades_gracefully_without_dependencies(client) -> None:
|
||||
resp = client.get("/api/health")
|
||||
assert resp.status_code == 200
|
||||
body = resp.json()
|
||||
@@ -53,13 +37,13 @@ def test_health_degrades_gracefully_without_dependencies() -> None:
|
||||
assert isinstance(body["ollama"], bool)
|
||||
|
||||
|
||||
def test_brands_returns_empty_list_without_database() -> None:
|
||||
def test_brands_returns_empty_list_without_database(client) -> None:
|
||||
resp = client.get("/api/brands")
|
||||
assert resp.status_code == 200
|
||||
assert resp.json() == {"brands": []}
|
||||
|
||||
|
||||
def test_brand_products_returns_empty_without_database() -> None:
|
||||
def test_brand_products_returns_empty_without_database(client) -> None:
|
||||
resp = client.get("/api/brands/Parle/products")
|
||||
assert resp.status_code == 200
|
||||
body = resp.json()
|
||||
@@ -68,30 +52,38 @@ def test_brand_products_returns_empty_without_database() -> None:
|
||||
assert body["total"] == 0
|
||||
|
||||
|
||||
def test_product_detail_404_when_missing() -> None:
|
||||
def test_product_detail_404_when_missing(client) -> None:
|
||||
resp = client.get("/api/brands/Parle/products/does-not-exist")
|
||||
assert resp.status_code == 404
|
||||
|
||||
|
||||
def test_chat_validates_empty_query() -> None:
|
||||
resp = client.post("/api/chat", json={"query": ""})
|
||||
# These now sign in first. The guard runs before body validation, so an
|
||||
# unauthenticated call gets 401 and never reaches the schema check these
|
||||
# assertions are actually about. tests/test_auth.py covers the guards
|
||||
# themselves.
|
||||
def test_chat_validates_empty_query(client, user_headers) -> None:
|
||||
resp = client.post("/api/chat", json={"query": ""}, headers=user_headers)
|
||||
assert resp.status_code == 422 # min_length=1 violated
|
||||
|
||||
|
||||
def test_chat_rejects_too_many_top_k() -> None:
|
||||
resp = client.post("/api/chat", json={"query": "snacks", "top_k": 999})
|
||||
def test_chat_rejects_too_many_top_k(client, user_headers) -> None:
|
||||
resp = client.post("/api/chat", json={"query": "snacks", "top_k": 999}, headers=user_headers)
|
||||
assert resp.status_code == 422 # le=15 violated
|
||||
|
||||
|
||||
def test_catalog_generate_returns_job_id() -> None:
|
||||
resp = client.post("/api/catalog/generate", json={"brand": "TestBrand", "max_products": 1})
|
||||
def test_catalog_generate_returns_job_id(client, admin_headers) -> None:
|
||||
resp = client.post(
|
||||
"/api/catalog/generate",
|
||||
json={"brand": "TestBrand", "max_products": 1},
|
||||
headers=admin_headers,
|
||||
)
|
||||
assert resp.status_code == 202
|
||||
body = resp.json()
|
||||
assert body["brand"] == "TestBrand"
|
||||
assert body["status"] in {"pending", "running", "done", "failed"}
|
||||
|
||||
|
||||
def test_openapi_schema_lists_all_routers() -> None:
|
||||
def test_openapi_schema_lists_all_routers(client) -> None:
|
||||
resp = client.get("/openapi.json")
|
||||
assert resp.status_code == 200
|
||||
paths = resp.json()["paths"]
|
||||
|
||||
Reference in New Issue
Block a user