diff --git a/app.py b/app.py index 5198539..5808e96 100644 --- a/app.py +++ b/app.py @@ -1,9 +1,6 @@ #!/usr/bin/env python3 from __future__ import annotations -import os -from pathlib import Path - from flask import Flask from auth import is_admin @@ -14,21 +11,6 @@ from storage import ensure_data_file from utils import cents_to_dollars, safe_date_label -def load_local_env(env_path: Path) -> None: - if not env_path.exists(): - return - - for raw_line in env_path.read_text(encoding="utf-8").splitlines(): - line = raw_line.strip() - if not line or line.startswith("#") or "=" not in line: - continue - - key, value = line.split("=", 1) - key = key.strip() - value = value.strip().strip('"').strip("'") - os.environ.setdefault(key, value) - - def create_app() -> Flask: app = Flask(__name__) app.config.from_object(Config) @@ -48,9 +30,6 @@ def create_app() -> Flask: return app -_env_path = Path(__file__).resolve().parent / ".env" -load_local_env(_env_path) - app = create_app() if __name__ == "__main__": diff --git a/config.py b/config.py index 442fec3..f1c9d6a 100644 --- a/config.py +++ b/config.py @@ -10,6 +10,24 @@ DATA_PATH = BASE_DIR / "data" / "entries.csv" ELIGIBLE_MIN_SESSIONS = 3 +def load_local_env(env_path: Path) -> None: + if not env_path.exists(): + return + + for raw_line in env_path.read_text(encoding="utf-8").splitlines(): + line = raw_line.strip() + if not line or line.startswith("#") or "=" not in line: + continue + + key, value = line.split("=", 1) + key = key.strip() + value = value.strip().strip('"').strip("'") + os.environ.setdefault(key, value) + + +load_local_env(BASE_DIR / ".env") + + class Config: SECRET_KEY: str = os.getenv("SECRET_KEY", "change-this-before-deploying") ADMIN_USERNAME: str = os.getenv("ADMIN_USERNAME", "admin") diff --git a/tests/test_stats.py b/tests/test_stats.py new file mode 100644 index 0000000..36ceaf3 --- /dev/null +++ b/tests/test_stats.py @@ -0,0 +1,85 @@ +import unittest + +from stats import SessionEntry, SessionSummary, build_leaderboard + + +class CashInAccountingTest(unittest.TestCase): + def test_front_recovered_from_cashout_counts_as_session_cash_in(self): + entry = SessionEntry( + session_id="2026-06-21-01", + session_date="2026-06-21", + player_name="Alex", + buy_in_cents=2500, + front_cents=500, + cash_out_cents=4000, + ) + session = SessionSummary( + session_id="2026-06-21-01", + session_date="2026-06-21", + entries=[entry], + ) + + self.assertEqual(session.total_buy_in_cents, 2500) + self.assertEqual(session.total_front_collected_cents, 0) + self.assertEqual(session.total_cash_in_cents, 3000) + + def test_collected_front_shortfall_counts_as_session_cash_in(self): + entry = SessionEntry( + session_id="2026-06-21-01", + session_date="2026-06-21", + player_name="Alex", + front_cents=1000, + cash_out_cents=400, + front_collected_cents=600, + ) + session = SessionSummary( + session_id="2026-06-21-01", + session_date="2026-06-21", + entries=[entry], + ) + + self.assertEqual(session.total_front_collected_cents, 600) + self.assertEqual(session.total_cash_in_cents, 1000) + + def test_written_off_front_does_not_count_as_session_cash_in(self): + entry = SessionEntry( + session_id="2026-06-21-01", + session_date="2026-06-21", + player_name="Blair", + front_cents=1000, + front_writeoff_cents=1000, + ) + session = SessionSummary( + session_id="2026-06-21-01", + session_date="2026-06-21", + entries=[entry], + ) + + self.assertEqual(session.total_front_writeoff_cents, 1000) + self.assertEqual(session.total_cash_in_cents, 0) + + def test_leaderboard_cash_in_includes_collected_fronts(self): + session = SessionSummary( + session_id="2026-06-21-01", + session_date="2026-06-21", + entries=[ + SessionEntry( + session_id="2026-06-21-01", + session_date="2026-06-21", + player_name="Alex", + buy_in_cents=2500, + front_cents=500, + cash_out_cents=4000, + ) + ], + ) + + player = build_leaderboard([session])[0] + + self.assertEqual(player.total_buy_in_cents, 2500) + self.assertEqual(player.total_front_collected_cents, 0) + self.assertEqual(player.total_cash_in_cents, 3000) + + +if __name__ == "__main__": + unittest.main()