179 lines
5.9 KiB
Python
179 lines
5.9 KiB
Python
"""
|
|
Tests for public API endpoints.
|
|
|
|
This module tests the public API endpoints for predictions and matches.
|
|
"""
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.main import app
|
|
from app.database import get_db
|
|
from app.models.prediction import Prediction
|
|
from app.models.match import Match
|
|
from datetime import datetime
|
|
|
|
|
|
client = TestClient(app)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_match(db: Session):
|
|
"""Create a sample match for testing."""
|
|
match = Match(
|
|
home_team="PSG",
|
|
away_team="Olympique de Marseille",
|
|
date=datetime.utcnow(),
|
|
league="Ligue 1",
|
|
status="scheduled"
|
|
)
|
|
db.add(match)
|
|
db.commit()
|
|
db.refresh(match)
|
|
return match
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_prediction(db: Session, sample_match: Match):
|
|
"""Create a sample prediction for testing."""
|
|
prediction = Prediction(
|
|
match_id=sample_match.id,
|
|
energy_score="high",
|
|
confidence="70.5%",
|
|
predicted_winner="PSG",
|
|
created_at=datetime.utcnow()
|
|
)
|
|
db.add(prediction)
|
|
db.commit()
|
|
db.refresh(prediction)
|
|
return prediction
|
|
|
|
|
|
class TestPublicPredictionsEndpoint:
|
|
"""Tests for GET /api/public/v1/predictions endpoint."""
|
|
|
|
def test_get_public_predictions_success(self, sample_prediction: Prediction):
|
|
"""Test successful retrieval of public predictions."""
|
|
response = client.get("/api/public/v1/predictions")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "data" in data
|
|
assert "meta" in data
|
|
assert isinstance(data["data"], list)
|
|
assert len(data["data"]) > 0
|
|
assert data["meta"]["version"] == "v1"
|
|
|
|
def test_get_public_predictions_with_limit(self, sample_prediction: Prediction):
|
|
"""Test retrieval of public predictions with limit parameter."""
|
|
response = client.get("/api/public/v1/predictions?limit=5")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "data" in data
|
|
assert "meta" in data
|
|
assert data["meta"]["limit"] == 5
|
|
|
|
def test_get_public_predictions_data_structure(self, sample_prediction: Prediction):
|
|
"""Test that public predictions have correct structure without sensitive data."""
|
|
response = client.get("/api/public/v1/predictions")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
prediction = data["data"][0]
|
|
|
|
# Required fields
|
|
assert "id" in prediction
|
|
assert "match" in prediction
|
|
assert "energy_score" in prediction
|
|
assert "confidence" in prediction
|
|
assert "predicted_winner" in prediction
|
|
|
|
# Match details
|
|
match = prediction["match"]
|
|
assert "id" in match
|
|
assert "home_team" in match
|
|
assert "away_team" in match
|
|
assert "date" in match
|
|
assert "league" in match
|
|
assert "status" in match
|
|
|
|
def test_get_public_predictions_empty_database(self):
|
|
"""Test retrieval when no predictions exist."""
|
|
# Clear database for this test
|
|
response = client.get("/api/public/v1/predictions")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "data" in data
|
|
assert isinstance(data["data"], list)
|
|
|
|
|
|
class TestPublicMatchesEndpoint:
|
|
"""Tests for GET /api/public/v1/matches endpoint."""
|
|
|
|
def test_get_public_matches_success(self, sample_match: Match):
|
|
"""Test successful retrieval of public matches."""
|
|
response = client.get("/api/public/v1/matches")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "data" in data
|
|
assert "meta" in data
|
|
assert isinstance(data["data"], list)
|
|
assert len(data["data"]) > 0
|
|
assert data["meta"]["version"] == "v1"
|
|
|
|
def test_get_public_matches_with_filters(self, sample_match: Match):
|
|
"""Test retrieval of public matches with league filter."""
|
|
response = client.get(f"/api/public/v1/matches?league=Ligue%201")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "data" in data
|
|
assert "meta" in data
|
|
|
|
def test_get_public_matches_data_structure(self, sample_match: Match):
|
|
"""Test that public matches have correct structure."""
|
|
response = client.get("/api/public/v1/matches")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
match = data["data"][0]
|
|
|
|
# Required fields (public only, no sensitive data)
|
|
assert "id" in match
|
|
assert "home_team" in match
|
|
assert "away_team" in match
|
|
assert "date" in match
|
|
assert "league" in match
|
|
assert "status" in match
|
|
|
|
def test_get_public_matches_empty_database(self):
|
|
"""Test retrieval when no matches exist."""
|
|
response = client.get("/api/public/v1/matches")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "data" in data
|
|
assert isinstance(data["data"], list)
|
|
|
|
|
|
class TestPublicApiResponseFormat:
|
|
"""Tests for standardized API response format."""
|
|
|
|
def test_response_format_success(self, sample_prediction: Prediction):
|
|
"""Test that successful responses follow {data, meta} format."""
|
|
response = client.get("/api/public/v1/predictions")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
assert "data" in data
|
|
assert "meta" in data
|
|
assert "timestamp" in data["meta"]
|
|
assert "version" in data["meta"]
|
|
|
|
def test_response_meta_timestamp_format(self, sample_prediction: Prediction):
|
|
"""Test that timestamp is in ISO 8601 format."""
|
|
response = client.get("/api/public/v1/predictions")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
timestamp = data["meta"]["timestamp"]
|
|
|
|
# ISO 8601 format check (simplified)
|
|
assert "T" in timestamp
|
|
assert "Z" in timestamp
|