""" tests/test_checker.py ---------------------- Tests for core/checker.py — ticket checking and prize tier logic. Draw data (Powerball): Draw 1 2024-01-01: [1, 13, 36, 61, 69] bonus=7 Draw 2 2024-01-03: [1, 2, 13, 45, 69] bonus=15 Draw 3 2024-01-05: [2, 13, 22, 36, 55] bonus=3 """ import pytest from db.models import get_game_by_name, insert_draw from core.checker import check_ticket, prize_tier, parse_numbers DRAWS = [ ("2024-01-01", [1, 13, 36, 61, 69], 7), ("2024-01-03", [1, 2, 13, 45, 69], 15), ("2024-01-05", [2, 13, 22, 36, 55], 3), ] @pytest.fixture def pb(tmp_db): game = get_game_by_name("Powerball") for date, nums, bonus in DRAWS: insert_draw(game["id"], date, nums, bonus=bonus) return game # ── prize_tier ──────────────────────────────────────────────────────────────── def test_jackpot(tmp_db): assert prize_tier(5, True) == "Jackpot" def test_match_5(tmp_db): assert prize_tier(5, False) == "Match 5" def test_match_4_bonus(tmp_db): assert prize_tier(4, True) == "Match 4 + Bonus" def test_match_4(tmp_db): assert prize_tier(4, False) == "Match 4" def test_match_3_bonus(tmp_db): assert prize_tier(3, True) == "Match 3 + Bonus" def test_match_3(tmp_db): assert prize_tier(3, False) == "Match 3" def test_match_2_bonus(tmp_db): assert prize_tier(2, True) == "Match 2 + Bonus" def test_match_1_bonus(tmp_db): assert prize_tier(1, True) == "Match 1 + Bonus" def test_bonus_only(tmp_db): assert prize_tier(0, True) == "Bonus Only" def test_no_prize(tmp_db): assert prize_tier(0, False) == "No Prize" def test_no_prize_2_no_bonus(tmp_db): assert prize_tier(2, False) == "No Prize" def test_no_prize_1_no_bonus(tmp_db): assert prize_tier(1, False) == "No Prize" # ── check_ticket — exact match ──────────────────────────────────────────────── def test_jackpot_ticket_found(pb): results = check_ticket(pb["id"], [1, 13, 36, 61, 69], bonus=7) assert len(results) >= 1 top = results[0] assert top["main_matches"] == 5 assert top["bonus_match"] is True assert top["prize_tier"] == "Jackpot" assert top["draw_date"] == "2024-01-01" def test_match_5_no_bonus(pb): results = check_ticket(pb["id"], [1, 13, 36, 61, 69], bonus=99) top = results[0] assert top["main_matches"] == 5 assert top["bonus_match"] is False assert top["prize_tier"] == "Match 5" def test_partial_match_3(pb): # Numbers 1, 13, 69 appear in draw 1 and draw 2 results = check_ticket(pb["id"], [1, 13, 69, 4, 8]) dates_matched = {r["draw_date"] for r in results} assert "2024-01-01" in dates_matched assert "2024-01-03" in dates_matched def test_bonus_only_match(pb): # No main number matches but bonus=7 matches draw 1 results = check_ticket(pb["id"], [3, 4, 5, 6, 7], bonus=7) bonus_only = [r for r in results if r["draw_date"] == "2024-01-01"] assert len(bonus_only) == 1 assert bonus_only[0]["main_matches"] == 0 assert bonus_only[0]["bonus_match"] is True assert bonus_only[0]["prize_tier"] == "Bonus Only" def test_no_match_returns_empty(pb): # Numbers that don't appear in any draw results = check_ticket(pb["id"], [3, 4, 5, 6, 7]) assert results == [] def test_no_bonus_in_ticket(pb): results = check_ticket(pb["id"], [1, 13, 36, 61, 69], bonus=None) top = results[0] assert top["bonus_match"] is False assert top["prize_tier"] == "Match 5" def test_results_sorted_by_matches_desc(pb): # Mix of matches: use numbers that appear in multiple draws with varying counts results = check_ticket(pb["id"], [1, 13, 36, 61, 69]) if len(results) > 1: for i in range(len(results) - 1): assert results[i]["main_matches"] >= results[i + 1]["main_matches"] def test_result_contains_required_keys(pb): results = check_ticket(pb["id"], [1, 13, 36, 61, 69]) for key in ("draw_date", "draw_numbers", "draw_bonus", "main_matches", "bonus_match", "prize_tier"): assert key in results[0] def test_empty_db_returns_empty(tmp_db): pb = get_game_by_name("Powerball") assert check_ticket(pb["id"], [1, 2, 3, 4, 5]) == [] # ── parse_numbers ───────────────────────────────────────────────────────────── def test_parse_space_separated(tmp_db): assert parse_numbers("7 14 32 56 68") == [7, 14, 32, 56, 68] def test_parse_comma_separated(tmp_db): assert parse_numbers("7,14,32,56,68") == [7, 14, 32, 56, 68] def test_parse_mixed_delimiters(tmp_db): assert parse_numbers("7, 14, 32") == [7, 14, 32] def test_parse_returns_sorted(tmp_db): assert parse_numbers("68 7 32") == [7, 32, 68] def test_parse_empty_raises(tmp_db): with pytest.raises(ValueError, match="No numbers"): parse_numbers(" ") def test_parse_non_digit_raises(tmp_db): with pytest.raises(ValueError): parse_numbers("7 14 abc")