feat: Feature 1.2 (NBA stats FastAPI service) + Feature 1.4 (database schema)
Feature 1.2: Python FastAPI microservice wrapping nba_api - GET /stats/season-avg, /stats/last-n, /stats/splits, /players/search - Redis caching (24hr/1hr/6hr/7day), 0.6s rate limiting, PRA derived stat - 27 Python tests passing Feature 1.4: Complete Supabase database schema - 6 tables: users, picks, scan_sessions, bets, outcomes, performance - RLS enabled on all tables with auth.uid() policies - 3 triggers: auto-create user, updated_at, scan count reset - 37 schema validation tests passing - Migration SQL ready, pending manual apply (WSL2 DNS blocker) Total: 92 tests (65 Node.js + 27 Python), all passing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
import pandas as pd
|
||||
|
||||
|
||||
MOCK_PLAYERS = [{"id": 203999, "full_name": "Nikola Jokic", "is_active": True}]
|
||||
|
||||
MOCK_CAREER_DF = pd.DataFrame([{
|
||||
"SEASON_ID": "2025-26",
|
||||
"TEAM_ABBREVIATION": "DEN",
|
||||
"PTS": 26.3, "REB": 12.4, "AST": 9.1, "FG3M": 1.1,
|
||||
"BLK": 0.7, "STL": 1.4, "TOV": 3.2, "MIN": 34.2, "GP": 65,
|
||||
}])
|
||||
|
||||
MOCK_GAMELOG_DF = pd.DataFrame([
|
||||
{
|
||||
"GAME_DATE": "MAR 21, 2026", "MATCHUP": "DEN vs. LAL",
|
||||
"TEAM_ABBREVIATION": "DEN",
|
||||
"PTS": 30, "REB": 15, "AST": 10, "FG3M": 2, "BLK": 1, "STL": 2, "TOV": 3, "MIN": 36,
|
||||
},
|
||||
{
|
||||
"GAME_DATE": "MAR 20, 2026", "MATCHUP": "DEN @ PHX",
|
||||
"TEAM_ABBREVIATION": "DEN",
|
||||
"PTS": 22, "REB": 10, "AST": 8, "FG3M": 0, "BLK": 0, "STL": 1, "TOV": 4, "MIN": 32,
|
||||
},
|
||||
{
|
||||
"GAME_DATE": "MAR 18, 2026", "MATCHUP": "DEN vs. LAL",
|
||||
"TEAM_ABBREVIATION": "DEN",
|
||||
"PTS": 28, "REB": 12, "AST": 9, "FG3M": 1, "BLK": 1, "STL": 1, "TOV": 2, "MIN": 35,
|
||||
},
|
||||
{
|
||||
"GAME_DATE": "MAR 16, 2026", "MATCHUP": "DEN @ GSW",
|
||||
"TEAM_ABBREVIATION": "DEN",
|
||||
"PTS": 24, "REB": 11, "AST": 7, "FG3M": 1, "BLK": 0, "STL": 2, "TOV": 3, "MIN": 33,
|
||||
},
|
||||
{
|
||||
"GAME_DATE": "MAR 14, 2026", "MATCHUP": "DEN vs. MIA",
|
||||
"TEAM_ABBREVIATION": "DEN",
|
||||
"PTS": 26, "REB": 13, "AST": 11, "FG3M": 2, "BLK": 1, "STL": 1, "TOV": 2, "MIN": 37,
|
||||
},
|
||||
])
|
||||
|
||||
|
||||
def _mock_career(*args, **kwargs):
|
||||
m = MagicMock()
|
||||
m.get_data_frames.return_value = [MOCK_CAREER_DF]
|
||||
return m
|
||||
|
||||
|
||||
def _mock_gamelog(*args, **kwargs):
|
||||
m = MagicMock()
|
||||
m.get_data_frames.return_value = [MOCK_GAMELOG_DF]
|
||||
return m
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_nba_api():
|
||||
"""Mocks all external dependencies: nba_api, Redis cache, rate limiter."""
|
||||
with patch("app.services.stats.playercareerstats.PlayerCareerStats", side_effect=_mock_career), \
|
||||
patch("app.services.stats.playergamelog.PlayerGameLog", side_effect=_mock_gamelog), \
|
||||
patch("app.utils.player_map.players.get_players", return_value=MOCK_PLAYERS), \
|
||||
patch("app.services.stats.cache_get", return_value=None), \
|
||||
patch("app.services.stats.cache_set"), \
|
||||
patch("app.utils.player_map.cache_get", return_value=None), \
|
||||
patch("app.utils.player_map.cache_set"), \
|
||||
patch("app.services.stats.time.sleep"):
|
||||
yield
|
||||
Reference in New Issue
Block a user