from datetime import datetime, timedelta, timezone import pytest import nightscout_client as ns class FakeResponse: def __init__(self, payload): self._payload = payload def raise_for_status(self): pass def json(self): return self._payload def test_mgdl_to_mmol_converts_correctly(): assert ns.mgdl_to_mmol(126.0) == pytest.approx(7.0, abs=0.05) def test_base_url_requires_nightscout_url(monkeypatch): monkeypatch.delenv("NIGHTSCOUT_URL", raising=False) with pytest.raises(ns.NightscoutConfigError): ns._base_url() def test_base_url_strips_trailing_slash(monkeypatch): monkeypatch.setenv("NIGHTSCOUT_URL", "https://example.com/") assert ns._base_url() == "https://example.com" def test_auth_prefers_token_over_api_secret(monkeypatch): monkeypatch.setenv("NIGHTSCOUT_TOKEN", "my-token") monkeypatch.setenv("NIGHTSCOUT_API_SECRET", "my-secret") headers, params = ns._auth() assert params == {"token": "my-token"} assert headers == {} def test_auth_hashes_api_secret(monkeypatch): monkeypatch.delenv("NIGHTSCOUT_TOKEN", raising=False) monkeypatch.setenv("NIGHTSCOUT_API_SECRET", "my-secret") headers, params = ns._auth() assert params == {} assert headers["API-SECRET"] != "my-secret" # nooit in plaintext assert len(headers["API-SECRET"]) == 40 # sha1 hexdigest def test_fetch_entries_converts_and_filters_by_time(monkeypatch): monkeypatch.setenv("NIGHTSCOUT_URL", "https://example.com") monkeypatch.delenv("NIGHTSCOUT_TOKEN", raising=False) monkeypatch.delenv("NIGHTSCOUT_API_SECRET", raising=False) now = datetime.now(timezone.utc) recent = now - timedelta(hours=1) too_old = now - timedelta(hours=48) payload = [ {"date": int(recent.timestamp() * 1000), "sgv": 126}, {"date": int(too_old.timestamp() * 1000), "sgv": 90}, ] monkeypatch.setattr(ns.requests, "get", lambda *a, **k: FakeResponse(payload)) result = ns.fetch_entries(hours=24) assert len(result) == 1 assert result.iloc[0]["mmol"] == pytest.approx(7.0, abs=0.05) def test_fetch_entries_handles_empty_response(monkeypatch): monkeypatch.setenv("NIGHTSCOUT_URL", "https://example.com") monkeypatch.setattr(ns.requests, "get", lambda *a, **k: FakeResponse([])) result = ns.fetch_entries(hours=24) assert result.empty assert list(result.columns) == ["timestamp", "mmol"] def test_fetch_treatments_fills_missing_columns(monkeypatch): monkeypatch.setenv("NIGHTSCOUT_URL", "https://example.com") now = datetime.now(timezone.utc) payload = [ {"created_at": now.isoformat(), "eventType": "Site Change"}, ] monkeypatch.setattr(ns.requests, "get", lambda *a, **k: FakeResponse(payload)) result = ns.fetch_treatments(hours=24) assert len(result) == 1 assert result.iloc[0]["eventType"] == "Site Change" assert pd_isna(result.iloc[0]["insulin"]) assert pd_isna(result.iloc[0]["carbs"]) def pd_isna(value): import pandas as pd return pd.isna(value)