""" tests/test_settings.py ----------------------- Tests for the Settings screen data layer and game-toggle logic. UI smoke tests run only when a display is available. """ import pytest from db.models import ( get_all_games, get_game_by_name, get_draw_count, set_game_active, insert_draw, insert_fetch_log, get_last_fetch_per_source, ) from db.database import get_db_stats # ── Game toggle (model layer) ───────────────────────────────────────────────── def test_game_starts_active(tmp_db): game = get_game_by_name("Powerball") assert game["active"] == 1 def test_disable_game(tmp_db): game = get_game_by_name("Powerball") set_game_active(game["id"], False) game = get_game_by_name("Powerball") assert game["active"] == 0 def test_enable_game_after_disable(tmp_db): game = get_game_by_name("Powerball") set_game_active(game["id"], False) set_game_active(game["id"], True) game = get_game_by_name("Powerball") assert game["active"] == 1 def test_disabled_game_excluded_from_active_only(tmp_db): game = get_game_by_name("Powerball") set_game_active(game["id"], False) active = get_all_games(active_only=True) names = [g["name"] for g in active] assert "Powerball" not in names assert "Mega Millions" in names # ── DB stats ────────────────────────────────────────────────────────────────── def test_db_stats_zero_on_fresh_db(tmp_db): stats = get_db_stats() assert all(v == 0 for v in stats.values()) def test_db_stats_reflects_inserts(tmp_db): pb = get_game_by_name("Powerball") insert_draw(pb["id"], "2024-01-01", [1, 2, 3, 4, 5], bonus=7) insert_draw(pb["id"], "2024-01-03", [5, 10, 20, 30, 40], bonus=15) stats = get_db_stats() assert stats["Powerball"] == 2 assert stats["Mega Millions"] == 0 def test_draw_count_matches_db_stats(tmp_db): pb = get_game_by_name("Powerball") insert_draw(pb["id"], "2024-01-01", [1, 2, 3, 4, 5], bonus=7) assert get_draw_count(pb["id"]) == get_db_stats()["Powerball"] # ── Last fetch per source ───────────────────────────────────────────────────── def test_last_fetch_empty_on_fresh_db(tmp_db): assert get_last_fetch_per_source() == {} def test_last_fetch_shows_all_sources(tmp_db): for src in ("powerball_ny", "megamillions_ny", "megamillions_tx"): insert_fetch_log(src, added=2, skipped=1, status="success") result = get_last_fetch_per_source() assert set(result.keys()) == {"powerball_ny", "megamillions_ny", "megamillions_tx"} def test_last_fetch_returns_most_recent(tmp_db): insert_fetch_log("powerball_ny", added=1, skipped=0, status="success", message=None) insert_fetch_log("powerball_ny", added=5, skipped=2, status="success", message=None) result = get_last_fetch_per_source() assert result["powerball_ny"]["added"] == 5 def test_last_fetch_error_status_preserved(tmp_db): insert_fetch_log("powerball_ny", added=0, skipped=0, status="error", message="timeout") result = get_last_fetch_per_source() assert result["powerball_ny"]["status"] == "error" # ── UI smoke tests ──────────────────────────────────────────────────────────── def _has_display(): try: import tkinter as tk r = tk.Tk() r.withdraw() r.destroy() return True except Exception: return False @pytest.mark.skipif(not _has_display(), reason="no display available") def test_settings_screen_instantiates(tmp_db): import tkinter as tk from ui.settings import SettingsScreen root = tk.Tk() root.withdraw() try: screen = SettingsScreen(root) screen.refresh() assert screen.winfo_exists() finally: root.destroy() @pytest.mark.skipif(not _has_display(), reason="no display available") def test_settings_game_toggle_updates_db(tmp_db): import tkinter as tk from ui.settings import SettingsScreen root = tk.Tk() root.withdraw() try: screen = SettingsScreen(root) screen.refresh() # Simulate unchecking Powerball via its BooleanVar pb = get_game_by_name("Powerball") var = screen._game_vars.get(pb["id"]) assert var is not None var.set(False) screen._toggle_game(pb["id"], var) pb_after = get_game_by_name("Powerball") assert pb_after["active"] == 0 finally: root.destroy() @pytest.mark.skipif(not _has_display(), reason="no display available") def test_settings_shows_fetch_history(tmp_db): import tkinter as tk from ui.settings import SettingsScreen insert_fetch_log("powerball_ny", added=3, skipped=1, status="success") root = tk.Tk() root.withdraw() try: screen = SettingsScreen(root) screen.refresh() # No assertion on widget text — just verify no exceptions during refresh assert screen.winfo_exists() finally: root.destroy()