mirror of
https://github.com/TronoSfera/Law.git
synced 2026-05-18 18:13:46 +03:00
152 lines
5.4 KiB
Python
152 lines
5.4 KiB
Python
import os
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
from botocore.exceptions import ClientError
|
|
from fastapi.testclient import TestClient
|
|
from sqlalchemy import create_engine, delete
|
|
from sqlalchemy.orm import sessionmaker
|
|
from sqlalchemy.pool import StaticPool
|
|
|
|
os.environ.setdefault("DATABASE_URL", "sqlite+pysqlite:///:memory:")
|
|
os.environ.setdefault("REDIS_URL", "redis://localhost:6379/0")
|
|
os.environ.setdefault("S3_ENDPOINT", "http://localhost:9000")
|
|
os.environ.setdefault("S3_ACCESS_KEY", "test")
|
|
os.environ.setdefault("S3_SECRET_KEY", "test")
|
|
os.environ.setdefault("S3_BUCKET", "test")
|
|
|
|
from app.db.session import get_db
|
|
from app.main import app
|
|
from app.models.admin_user import AdminUser
|
|
from app.models.landing_featured_staff import LandingFeaturedStaff
|
|
from app.models.topic import Topic
|
|
|
|
|
|
class _FakeBody:
|
|
def __init__(self, payload: bytes):
|
|
self.payload = payload
|
|
|
|
def iter_chunks(self, chunk_size=65536):
|
|
for i in range(0, len(self.payload), chunk_size):
|
|
yield self.payload[i : i + chunk_size]
|
|
|
|
|
|
class _FakeS3Storage:
|
|
def __init__(self):
|
|
self.objects = {}
|
|
|
|
def get_object(self, key: str) -> dict:
|
|
obj = self.objects.get(key)
|
|
if obj is None:
|
|
raise ClientError({"Error": {"Code": "404", "Message": "Not Found"}}, "GetObject")
|
|
return {"Body": _FakeBody(obj["content"]), "ContentType": obj["mime"], "ContentLength": obj["size"]}
|
|
|
|
|
|
class FeaturedStaffPublicTests(unittest.TestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.engine = create_engine(
|
|
"sqlite+pysqlite:///:memory:",
|
|
connect_args={"check_same_thread": False},
|
|
poolclass=StaticPool,
|
|
)
|
|
cls.SessionLocal = sessionmaker(bind=cls.engine, autocommit=False, autoflush=False)
|
|
AdminUser.__table__.create(bind=cls.engine)
|
|
Topic.__table__.create(bind=cls.engine)
|
|
LandingFeaturedStaff.__table__.create(bind=cls.engine)
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
LandingFeaturedStaff.__table__.drop(bind=cls.engine)
|
|
Topic.__table__.drop(bind=cls.engine)
|
|
AdminUser.__table__.drop(bind=cls.engine)
|
|
cls.engine.dispose()
|
|
|
|
def setUp(self):
|
|
with self.SessionLocal() as db:
|
|
db.execute(delete(LandingFeaturedStaff))
|
|
db.execute(delete(Topic))
|
|
db.execute(delete(AdminUser))
|
|
db.commit()
|
|
|
|
def override_get_db():
|
|
db = self.SessionLocal()
|
|
try:
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
app.dependency_overrides[get_db] = override_get_db
|
|
self.client = TestClient(app)
|
|
|
|
def tearDown(self):
|
|
self.client.close()
|
|
app.dependency_overrides.clear()
|
|
|
|
def _seed_featured_lawyer(self, enabled: bool = True):
|
|
with self.SessionLocal() as db:
|
|
topic = Topic(code="consulting", name="consulting", enabled=True, sort_order=1)
|
|
user = AdminUser(
|
|
role="LAWYER",
|
|
name="Юрист",
|
|
email="lawyer-featured@example.com",
|
|
password_hash="hash",
|
|
is_active=True,
|
|
primary_topic_code="consulting",
|
|
)
|
|
db.add_all([topic, user])
|
|
db.flush()
|
|
avatar_key = f"avatars/{user.id}/avatar.webp"
|
|
user.avatar_url = "s3://" + avatar_key
|
|
slot = LandingFeaturedStaff(
|
|
admin_user_id=user.id,
|
|
caption="Я крут!",
|
|
sort_order=10,
|
|
pinned=True,
|
|
enabled=enabled,
|
|
)
|
|
db.add(slot)
|
|
db.commit()
|
|
return str(user.id), avatar_key
|
|
|
|
def test_list_featured_staff_returns_public_avatar_proxy_url(self):
|
|
user_id, _ = self._seed_featured_lawyer(enabled=True)
|
|
|
|
response = self.client.get("/api/public/featured-staff?limit=24")
|
|
self.assertEqual(response.status_code, 200)
|
|
payload = response.json()
|
|
self.assertEqual(payload.get("total"), 1)
|
|
self.assertEqual(len(payload.get("items") or []), 1)
|
|
row = payload["items"][0]
|
|
self.assertEqual(row.get("admin_user_id"), user_id)
|
|
self.assertEqual(row.get("avatar_url"), "/api/public/featured-staff/avatar/" + user_id)
|
|
|
|
def test_featured_staff_avatar_proxy_streams_s3_avatar(self):
|
|
user_id, avatar_key = self._seed_featured_lawyer(enabled=True)
|
|
fake_s3 = _FakeS3Storage()
|
|
fake_s3.objects[avatar_key] = {
|
|
"size": 7,
|
|
"mime": "image/webp",
|
|
"content": b"webpimg",
|
|
}
|
|
|
|
with patch("app.api.public.featured_staff.get_s3_storage", return_value=fake_s3):
|
|
response = self.client.get("/api/public/featured-staff/avatar/" + user_id)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.content, b"webpimg")
|
|
self.assertIn("image/webp", response.headers.get("content-type", ""))
|
|
|
|
def test_featured_staff_avatar_proxy_denies_non_featured_user(self):
|
|
user_id, avatar_key = self._seed_featured_lawyer(enabled=False)
|
|
fake_s3 = _FakeS3Storage()
|
|
fake_s3.objects[avatar_key] = {
|
|
"size": 7,
|
|
"mime": "image/webp",
|
|
"content": b"webpimg",
|
|
}
|
|
|
|
with patch("app.api.public.featured_staff.get_s3_storage", return_value=fake_s3):
|
|
response = self.client.get("/api/public/featured-staff/avatar/" + user_id)
|
|
|
|
self.assertEqual(response.status_code, 404)
|