""" tests/test_dashboard.py ------------------------ Tests for the Dashboard screen data layer and UI smoke tests. """ import pytest from db.models import ( get_all_games, get_game_by_name, get_last_draw, insert_draw, insert_prediction, ) from db.database import get_db_stats from core.analyzer import frequency_analysis # ── Data-layer checks used by the Dashboard ─────────────────────────────────── def test_last_draw_none_on_empty_db(tmp_db): pb = get_game_by_name("Powerball") assert get_last_draw(pb["id"]) is None def test_last_draw_returns_most_recent(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-05", [5, 10, 20, 30, 40], bonus=15) last = get_last_draw(pb["id"]) assert last["draw_date"] == "2024-01-05" def test_last_draw_numbers_parseable(tmp_db): pb = get_game_by_name("Powerball") insert_draw(pb["id"], "2024-01-01", [1, 13, 36, 61, 69], bonus=7) last = get_last_draw(pb["id"]) nums = [int(n) for n in last["numbers"].split(",")] assert sorted(nums) == [1, 13, 36, 61, 69] def test_db_stats_all_games_present(tmp_db): stats = get_db_stats() assert "Powerball" in stats assert "Mega Millions" in stats def test_db_stats_counts_correct_after_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_hot_numbers_empty_returns_empty(tmp_db): pb = get_game_by_name("Powerball") assert frequency_analysis(pb["id"], last_n=100) == {} def test_hot_numbers_top5_correct(tmp_db): pb = get_game_by_name("Powerball") # Insert 3 draws; numbers 1 and 13 appear most (3 times each) insert_draw(pb["id"], "2024-01-01", [1, 13, 36, 61, 69], bonus=7) insert_draw(pb["id"], "2024-01-03", [1, 2, 13, 45, 69], bonus=15) insert_draw(pb["id"], "2024-01-05", [1, 13, 22, 36, 55], bonus=3) freq = frequency_analysis(pb["id"], last_n=100) top5 = sorted(freq, key=freq.get, reverse=True)[:5] assert 1 in top5 assert 13 in top5 def test_predictions_count_correct(tmp_db): from db.models import get_predictions pb = get_game_by_name("Powerball") insert_prediction(pb["id"], "Hot Numbers", [1, 2, 3, 4, 5], bonus=7) insert_prediction(pb["id"], "Due Numbers", [5, 10, 20, 30, 40], bonus=15) assert len(get_predictions(limit=100_000)) == 2 # ── 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_dashboard_instantiates(tmp_db): import tkinter as tk from ui.dashboard import DashboardScreen root = tk.Tk(); root.withdraw() try: screen = DashboardScreen(root) screen.refresh() assert screen.winfo_exists() finally: root.destroy() @pytest.mark.skipif(not _has_display(), reason="no display available") def test_dashboard_refresh_with_data(tmp_db): import tkinter as tk from ui.dashboard import DashboardScreen pb = get_game_by_name("Powerball") insert_draw(pb["id"], "2024-01-01", [1, 13, 36, 61, 69], bonus=7, multiplier="2x") root = tk.Tk(); root.withdraw() try: screen = DashboardScreen(root) screen.refresh() assert screen.winfo_exists() finally: root.destroy() @pytest.mark.skipif(not _has_display(), reason="no display available") def test_dashboard_refresh_empty_db(tmp_db): import tkinter as tk from ui.dashboard import DashboardScreen root = tk.Tk(); root.withdraw() try: screen = DashboardScreen(root) screen.refresh() assert screen.winfo_exists() finally: root.destroy() @pytest.mark.skipif(not _has_display(), reason="no display available") def test_dashboard_on_fetch_callback(tmp_db): import tkinter as tk from ui.dashboard import DashboardScreen called = [] root = tk.Tk(); root.withdraw() try: screen = DashboardScreen(root, on_fetch=lambda: called.append(1)) screen.refresh() assert screen.winfo_exists() finally: root.destroy()