""" tests/test_saved_predictions.py -------------------------------- Tests for the saved-prediction model functions (delete_prediction, delete_all_predictions) and the _count_matches helper in predictor_ui. """ import pytest from db.models import ( get_game_by_name, insert_draw, insert_prediction, get_predictions, delete_prediction, delete_all_predictions, get_last_draw, ) from ui.predictor_ui import _count_matches # ── Fixtures ────────────────────────────────────────────────────────────────── @pytest.fixture def pb(tmp_db): return get_game_by_name("Powerball") @pytest.fixture def mm(tmp_db): return get_game_by_name("Mega Millions") @pytest.fixture def with_predictions(pb, mm): insert_draw(pb["id"], "2024-01-01", [1, 13, 36, 61, 69], bonus=7) p1 = insert_prediction(pb["id"], "Hot Numbers", [1, 13, 36, 61, 69], bonus=7) p2 = insert_prediction(pb["id"], "Due Numbers", [5, 10, 20, 30, 40], bonus=15) p3 = insert_prediction(mm["id"], "Monte Carlo", [2, 14, 37, 62, 70], bonus=5) return p1, p2, p3 # ── delete_prediction ───────────────────────────────────────────────────────── def test_delete_prediction_removes_row(pb, with_predictions): p1, p2, p3 = with_predictions delete_prediction(p1) ids = [p["id"] for p in get_predictions(limit=100_000)] assert p1 not in ids assert p2 in ids def test_delete_prediction_leaves_others_intact(pb, with_predictions): p1, p2, p3 = with_predictions delete_prediction(p1) remaining = get_predictions(limit=100_000) assert len(remaining) == 2 def test_delete_nonexistent_prediction_no_error(tmp_db): delete_prediction(99999) # should not raise # ── delete_all_predictions ──────────────────────────────────────────────────── def test_delete_all_clears_everything(pb, with_predictions): delete_all_predictions() assert get_predictions(limit=100_000) == [] def test_delete_all_with_game_id_only_removes_that_game(pb, mm, with_predictions): p1, p2, p3 = with_predictions delete_all_predictions(game_id=pb["id"]) remaining = get_predictions(limit=100_000) assert len(remaining) == 1 assert remaining[0]["id"] == p3 def test_delete_all_empty_db_no_error(tmp_db): delete_all_predictions() # should not raise def test_delete_all_game_id_no_match_no_error(pb, tmp_db): delete_all_predictions(game_id=pb["id"]) # nothing to delete # ── _count_matches ──────────────────────────────────────────────────────────── def test_count_matches_full_match(pb): insert_draw(pb["id"], "2024-01-01", [1, 13, 36, 61, 69], bonus=7) last = get_last_draw(pb["id"]) assert _count_matches("1,13,36,61,69", last) == "5/5" def test_count_matches_partial(pb): insert_draw(pb["id"], "2024-01-01", [1, 13, 36, 61, 69], bonus=7) last = get_last_draw(pb["id"]) assert _count_matches("1,13,2,3,4", last) == "2/5" def test_count_matches_zero(pb): insert_draw(pb["id"], "2024-01-01", [1, 13, 36, 61, 69], bonus=7) last = get_last_draw(pb["id"]) assert _count_matches("2,3,4,5,6", last) == "0/5" def test_count_matches_no_last_draw(tmp_db): pb = get_game_by_name("Powerball") assert _count_matches("1,2,3,4,5", None) == "—" # ── 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_predictor_screen_saved_tab_loads(tmp_db): import tkinter as tk from ui.predictor_ui import PredictorScreen root = tk.Tk(); root.withdraw() try: screen = PredictorScreen(root) screen.refresh() assert screen.winfo_exists() finally: root.destroy() @pytest.mark.skipif(not _has_display(), reason="no display available") def test_saved_tab_shows_predictions(tmp_db): import tkinter as tk from ui.predictor_ui import PredictorScreen pb = get_game_by_name("Powerball") insert_prediction(pb["id"], "Hot Numbers", [1, 13, 36, 61, 69], bonus=7) root = tk.Tk(); root.withdraw() try: screen = PredictorScreen(root) screen.refresh() children = screen._saved_tree.get_children() assert len(children) == 1 finally: root.destroy() @pytest.mark.skipif(not _has_display(), reason="no display available") def test_saved_tab_delete_selected(tmp_db): import tkinter as tk from ui.predictor_ui import PredictorScreen pb = get_game_by_name("Powerball") pid = insert_prediction(pb["id"], "Hot Numbers", [1, 13, 36, 61, 69], bonus=7) root = tk.Tk(); root.withdraw() try: screen = PredictorScreen(root) screen.refresh() iid = screen._saved_tree.get_children()[0] screen._saved_tree.selection_set(iid) screen._delete_selected() assert len(screen._saved_tree.get_children()) == 0 assert get_predictions(limit=100_000) == [] finally: root.destroy()