from __future__ import annotations from datetime import datetime, timedelta, timezone from fastapi.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy.orm import Session from sqlalchemy.pool import StaticPool from app.database import Base, get_session from app.main import app from app.models import Bait, BaitKind, CatchReport, Fish, ModerationStatus, SourceType, Spot, Waterbody engine = create_engine("sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool) Base.metadata.create_all(engine) def override_session(): with Session(engine) as session: yield session app.dependency_overrides[get_session] = override_session client = TestClient(app) def setup_module() -> None: with Session(engine) as db: waterbody = Waterbody(slug="test-lake", name_ru="Тестовое озеро", unlock_level=1) fish = Fish(slug="pike", name_ru="Щука", trophy_weight_g=10_000) bait = Bait(name="Тестовая приманка", normalized_name="тестовая приманка", kind=BaitKind.lure) spot = Spot(waterbody=waterbody, x=10, y=20, description="Тестовая точка") db.add_all([waterbody, fish, bait, spot]) now = datetime.now(timezone.utc) for index in range(3): db.add(CatchReport(fish=fish, spot=spot, waterbody=waterbody, bait=bait, weight_g=3000 + index * 1000, fishing_method="spinning", reported_at=now - timedelta(hours=index), caught_at=now - timedelta(hours=index), player_name=f"Player {index}", source_type=SourceType.manual_import, source_confidence=90, moderation_status=ModerationStatus.approved)) db.commit() def test_activity_filters_and_explains_score() -> None: response = client.get("/api/v1/activity?waterbody=test-lake&fish=pike&hours=24") assert response.status_code == 200 payload = response.json() assert len(payload) == 1 assert payload[0]["catches"] == 3 assert payload[0]["unique_players"] == 3 assert "3 свежих уловов" in payload[0]["explanation"] def test_invalid_period_is_rejected() -> None: assert client.get("/api/v1/activity?hours=13").status_code == 422 def test_spot_detail_and_catches() -> None: spot_id = client.get("/api/v1/activity").json()[0]["spot_id"] detail = client.get(f"/api/v1/spots/{spot_id}") catches = client.get(f"/api/v1/spots/{spot_id}/catches") assert detail.status_code == 200 assert detail.json()["catches_24h"] == 3 assert catches.status_code == 200 assert len(catches.json()) == 3 def test_records_list_is_empty_before_import() -> None: response = client.get("/api/v1/records") assert response.status_code == 200 assert response.json() == []