import json from datetime import timezone from zoneinfo import ZoneInfo from unittest.mock import patch, MagicMock from hyprsunset_qt.sun import to_local_hm, read_cache, write_cache, geolocate, fetch_sun, _http_get def test_utc_to_local_hm(): # 2026-07-17T17:40:00+00:00 -> 19:40 in Europe/Rome (UTC+2 summer) tz = ZoneInfo("Europe/Rome") assert to_local_hm("2026-07-17T17:40:00+00:00", tz) == "19:40" def test_cache_roundtrip(tmp_path): path = tmp_path / "sun.json" payload = {"lat": "45.07", "lon": "7.68", "results": {"sunset": "x"}} write_cache(payload, path) assert read_cache(path) == payload def test_read_cache_missing(tmp_path): assert read_cache(tmp_path / "nope.json") is None def test_http_get_sends_user_agent(): # sunrise-sunset.org sits behind Cloudflare, which 403s the default # Python-urllib User-Agent (error 1010). _http_get must send a real UA. resp = MagicMock() resp.read.return_value = b"{}" resp.__enter__.return_value = resp resp.__exit__.return_value = False with patch("hyprsunset_qt.sun.urllib.request.urlopen", return_value=resp) as uo: _http_get("https://example.com/x") req = uo.call_args[0][0] # urlopen was called with a Request carrying a non-default User-Agent assert req.get_header("User-agent") assert "urllib" not in req.get_header("User-agent").lower() def test_geolocate_parses_latlon(): body = json.dumps({"status": "success", "lat": 45.07, "lon": 7.68}) with patch("hyprsunset_qt.sun._http_get", return_value=body): assert geolocate() == ("45.07", "7.68") def test_fetch_sun_returns_results_dict(): body = json.dumps({ "status": "OK", "results": { "sunrise": "2026-07-17T03:12:00+00:00", "sunset": "2026-07-17T17:40:00+00:00", }, }) with patch("hyprsunset_qt.sun._http_get", return_value=body) as g: out = fetch_sun("45.07", "7.68") assert out["results"]["sunset"] == "2026-07-17T17:40:00+00:00" url = g.call_args[0][0] assert "lat=45.07" in url and "lng=7.68" in url and "formatted=0" in url