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

1import json 

2from typing import Any, cast 

3from urllib.request import Request 

4 

5import pytest 

6 

7from app.analytics.posthog import capture_package_requested_events 

8from app.core.config import settings 

9 

10 

11class DummyResponse: 

12 def __enter__(self) -> "DummyResponse": 

13 return self 

14 

15 def __exit__(self, exc_type: Any, exc: Any, traceback: Any) -> None: 

16 return None 

17 

18 

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) 

35 

36 calls = 0 

37 

38 def fake_urlopen(*args: Any, **kwargs: Any) -> DummyResponse: 

39 nonlocal calls 

40 calls += 1 

41 return DummyResponse() 

42 

43 monkeypatch.setattr("app.analytics.posthog.urlopen", fake_urlopen) 

44 

45 capture_package_requested_events( 

46 packages=packages, 

47 time_range="3months", 

48 show_percentage=False, 

49 hx_trigger="dataRefresh", 

50 ) 

51 

52 assert calls == 0 

53 

54 

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") 

61 

62 request_payloads: list[dict[str, Any]] = [] 

63 request_urls: list[str] = [] 

64 

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() 

71 

72 monkeypatch.setattr("app.analytics.posthog.urlopen", fake_urlopen) 

73 

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 ) 

81 

82 assert len(request_payloads) == 2 

83 assert all(url == "https://us.i.posthog.com/capture/" for url in request_urls) 

84 

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" 

96 

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"