1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
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
|