"""Tests for scrapers.py — uses mocks to avoid real HTTP calls.""" from __future__ import annotations from unittest.mock import MagicMock, patch from scrapers import ( _parse_jackpot_from_lotto_net, clear_cache, get_all_jackpots, scrape_mega_millions, scrape_powerball, ) # --------------------------------------------------------------------------- # HTML parser unit tests # --------------------------------------------------------------------------- POWERBALL_HTML = """

Powerball

Next Jackpot $350 Million
""" BILLION_HTML = """
Next Jackpot $1.5 Billion
""" def test_parse_jackpot_millions(): result = _parse_jackpot_from_lotto_net(POWERBALL_HTML) assert result == 350_000_000 def test_parse_jackpot_billions(): result = _parse_jackpot_from_lotto_net(BILLION_HTML) assert result == 1_500_000_000 def test_parse_jackpot_no_match(): result = _parse_jackpot_from_lotto_net("No jackpot here") assert result is None # --------------------------------------------------------------------------- # Scraper integration tests (mocked HTTP) # --------------------------------------------------------------------------- @patch("scrapers.requests.get") def test_scrape_powerball_success(mock_get): mock_resp = MagicMock() mock_resp.text = POWERBALL_HTML mock_resp.raise_for_status = MagicMock() mock_get.return_value = mock_resp result = scrape_powerball() assert result == 350_000_000 @patch("scrapers.requests.get") def test_scrape_powerball_failure(mock_get): mock_get.side_effect = Exception("Network error") result = scrape_powerball() assert result is None @patch("scrapers.requests.get") def test_scrape_mega_millions_success(mock_get): html = POWERBALL_HTML.replace("Powerball", "Mega Millions") mock_resp = MagicMock() mock_resp.text = html mock_resp.raise_for_status = MagicMock() mock_get.return_value = mock_resp result = scrape_mega_millions() assert result == 350_000_000 # --------------------------------------------------------------------------- # Cache tests # --------------------------------------------------------------------------- @patch("scrapers.scrape_powerball", return_value=100_000_000) @patch("scrapers.scrape_mega_millions", return_value=200_000_000) @patch("scrapers.scrape_canadian_lotteries", return_value={"lottoMax": 50_000_000, "lotto649": 10_000_000}) def test_get_all_jackpots_caches(mock_ca, mock_mm, mock_pb): clear_cache() r1 = get_all_jackpots() r2 = get_all_jackpots() # Second call should use cache — scrapers called only once assert mock_pb.call_count == 1 assert r1 == r2 @patch("scrapers.scrape_powerball", return_value=100_000_000) @patch("scrapers.scrape_mega_millions", return_value=200_000_000) @patch("scrapers.scrape_canadian_lotteries", return_value={"lottoMax": 50_000_000, "lotto649": 10_000_000}) def test_get_all_jackpots_force_refresh(mock_ca, mock_mm, mock_pb): clear_cache() get_all_jackpots() get_all_jackpots(force_refresh=True) assert mock_pb.call_count == 2