system-prompts-and-models-o.../dealix/tests/unit/test_api_key_middleware.py
2026-05-01 14:03:52 +03:00

70 lines
2.0 KiB
Python

"""
Unit tests for APIKeyMiddleware path policy.
Verifies:
* /api/v1/pricing/plans is PUBLIC (prospects must see pricing without a key).
* /api/v1/checkout still requires an API key.
* Webhooks prefix stays public (signature-verified separately).
"""
from __future__ import annotations
import os
import pytest
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from starlette.testclient import TestClient
from api.security.api_key import PUBLIC_PATHS, APIKeyMiddleware
@pytest.fixture()
def app_with_keys(monkeypatch: pytest.MonkeyPatch) -> FastAPI:
monkeypatch.setenv("API_KEYS", "test-secret-key")
app = FastAPI()
app.add_middleware(APIKeyMiddleware)
@app.get("/api/v1/pricing/plans")
def plans() -> JSONResponse:
return JSONResponse({"plans": []})
@app.post("/api/v1/checkout")
def checkout() -> JSONResponse:
return JSONResponse({"ok": True})
@app.post("/api/v1/webhooks/moyasar")
def moyasar() -> JSONResponse:
return JSONResponse({"ok": True})
return app
def test_pricing_plans_is_public(app_with_keys: FastAPI) -> None:
client = TestClient(app_with_keys)
r = client.get("/api/v1/pricing/plans")
assert r.status_code == 200, r.text
def test_pricing_plans_in_public_paths_constant() -> None:
# Regression guard: ensure nobody removes this entry without updating tests.
assert "/api/v1/pricing/plans" in PUBLIC_PATHS
def test_checkout_requires_api_key(app_with_keys: FastAPI) -> None:
client = TestClient(app_with_keys)
r = client.post("/api/v1/checkout", json={})
assert r.status_code == 401
def test_checkout_accepts_valid_key(app_with_keys: FastAPI) -> None:
client = TestClient(app_with_keys)
r = client.post("/api/v1/checkout", json={}, headers={"X-API-Key": "test-secret-key"})
assert r.status_code == 200
def test_webhook_path_is_public(app_with_keys: FastAPI) -> None:
client = TestClient(app_with_keys)
r = client.post("/api/v1/webhooks/moyasar", json={})
assert r.status_code == 200