Coverage for app/tests/test_analytics_posthog.py: 96%
53 statements
« prev ^ index » next coverage.py v7.6.10, created at 2026-06-04 22:29 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2026-06-04 22:29 +0000
1import json
2from typing import Any, cast
3from urllib.request import Request
5import pytest
7from app.analytics.posthog import capture_package_requested_events
8from app.core.config import settings
11class DummyResponse:
12 def __enter__(self) -> "DummyResponse":
13 return self
15 def __exit__(self, exc_type: Any, exc: Any, traceback: Any) -> None:
16 return None
19@pytest.mark.parametrize(
20 ("enabled", "api_key", "packages"),
21 [
22 (False, "test_api_key", ["duckdb"]),
23 (True, None, ["duckdb"]),
24 (True, "test_api_key", []),
25 ],
26)
27def test_capture_package_requested_events_noop(
28 monkeypatch: pytest.MonkeyPatch,
29 enabled: bool,
30 api_key: str | None,
31 packages: list[str],
32) -> None:
33 monkeypatch.setattr(settings, "ENABLE_SERVER_ANALYTICS", enabled)
34 monkeypatch.setattr(settings, "POSTHOG_API_KEY", api_key)
36 calls = 0
38 def fake_urlopen(*args: Any, **kwargs: Any) -> DummyResponse:
39 nonlocal calls
40 calls += 1
41 return DummyResponse()
43 monkeypatch.setattr("app.analytics.posthog.urlopen", fake_urlopen)
45 capture_package_requested_events(
46 packages=packages,
47 time_range="3months",
48 show_percentage=False,
49 hx_trigger="dataRefresh",
50 )
52 assert calls == 0
55def test_capture_package_requested_events_emits_one_per_package(
56 monkeypatch: pytest.MonkeyPatch,
57) -> None:
58 monkeypatch.setattr(settings, "ENABLE_SERVER_ANALYTICS", True)
59 monkeypatch.setattr(settings, "POSTHOG_API_KEY", "test_api_key")
60 monkeypatch.setattr(settings, "POSTHOG_HOST", "https://us.i.posthog.com")
62 request_payloads: list[dict[str, Any]] = []
63 request_urls: list[str] = []
65 def fake_urlopen(request: Request, timeout: int) -> DummyResponse:
66 request_urls.append(request.full_url)
67 data = cast(bytes, request.data)
68 request_payloads.append(json.loads(data.decode("utf-8")))
69 assert timeout == 2
70 return DummyResponse()
72 monkeypatch.setattr("app.analytics.posthog.urlopen", fake_urlopen)
74 capture_package_requested_events(
75 packages=["pandas", "duckdb"],
76 time_range="3months",
77 show_percentage=True,
78 hx_trigger="dataRefresh",
79 request_id="req-123",
80 )
82 assert len(request_payloads) == 2
83 assert all(url == "https://us.i.posthog.com/capture/" for url in request_urls)
85 first_payload = request_payloads[0]
86 assert first_payload["event"] == "package_requested"
87 assert first_payload["api_key"] == "test_api_key"
88 assert first_payload["distinct_id"] == "server"
89 assert first_payload["properties"]["package"] == "duckdb"
90 assert first_payload["properties"]["packages"] == ["duckdb", "pandas"]
91 assert first_payload["properties"]["time_range"] == "3months"
92 assert first_payload["properties"]["show_percentage"] is True
93 assert first_payload["properties"]["hx_trigger"] == "dataRefresh"
94 assert first_payload["properties"]["request_id"] == "req-123"
95 assert first_payload["properties"]["source"] == "server_htmx"
97 second_payload = request_payloads[1]
98 assert second_payload["properties"]["package"] == "pandas"
99 assert second_payload["properties"]["packages"] == ["duckdb", "pandas"]
100 assert second_payload["properties"]["request_id"] == "req-123"