05/23 Phase 9
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
"""
|
||||
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()
|
||||
Reference in New Issue
Block a user