TorbatYar/backend/services/loyalty/app/tests/test_security.py
Mortezakoohjani e41ecfad4c Sync platform docs, infra, and module services with Accounting integration.
Include Loyalty/Communication/Sports Center backends and registry updates alongside production nginx and compose wiring.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-25 22:35:23 +03:30

69 lines
2.5 KiB
Python

"""Security tests — auth required and error hygiene."""
from __future__ import annotations
import pytest
from httpx import ASGITransport, AsyncClient
from app.core.config import settings
from app.core.security import get_current_user
from app.main import app
from app.tests.conftest import TENANT_A, tenant_headers
from shared.exceptions import UnauthorizedError
from shared.security import CurrentUser
@pytest.mark.asyncio
async def test_unauthenticated_denied_when_auth_required(db_setup, monkeypatch):
monkeypatch.setattr(settings, "auth_required", True)
async def _deny():
raise UnauthorizedError("توکن احراز هویت ارائه نشده است")
app.dependency_overrides[get_current_user] = _deny
try:
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://testserver") as ac:
resp = await ac.get(
"/api/v1/programs", headers=tenant_headers(TENANT_A)
)
assert resp.status_code == 401
body = resp.json()
assert "error" in body
assert "traceback" not in str(body).lower()
assert "superapp_password" not in str(body)
finally:
app.dependency_overrides.pop(get_current_user, None)
monkeypatch.setattr(settings, "auth_required", False)
@pytest.mark.asyncio
async def test_permission_denied_for_viewer_role(db_setup, monkeypatch):
monkeypatch.setattr(settings, "auth_required", True)
async def _viewer():
return CurrentUser(user_id="viewer", roles=["tenant_viewer"])
app.dependency_overrides[get_current_user] = _viewer
try:
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://testserver") as ac:
resp = await ac.post(
"/api/v1/programs",
json={"code": "SEC", "name": "Secured"},
headers=tenant_headers(TENANT_A),
)
assert resp.status_code == 403
assert resp.json()["error"]["code"] in {"forbidden", "permission_denied"}
finally:
app.dependency_overrides.pop(get_current_user, None)
monkeypatch.setattr(settings, "auth_required", False)
@pytest.mark.asyncio
async def test_invalid_tenant_header(client):
resp = await client.get(
"/api/v1/programs", headers={"X-Tenant-ID": "not-a-uuid"}
)
assert resp.status_code == 400
assert resp.json()["error"]["code"] == "invalid_tenant_id"