Skip to content

Commit 8947041

Browse files
committed
test: convert telemetry test helpers to pytest fixtures
Replace repeated _patch_event_defaults/_mock_event_defaults calls with event_defaults and httpx_post fixtures so each test's setup stays in its signature instead of the body.
1 parent e7711f7 commit 8947041

1 file changed

Lines changed: 43 additions & 49 deletions

File tree

tests/units/test_telemetry.py

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,15 @@
55
from reflex.utils import telemetry
66

77

8-
def _mock_event_defaults() -> dict:
9-
return {
8+
@pytest.fixture
9+
def event_defaults(mocker: MockerFixture) -> dict:
10+
"""Patch ``get_event_defaults()`` with a fresh dict.
11+
12+
Returns:
13+
The dict that ``get_event_defaults()`` is patched to return, so tests
14+
can assert it isn't mutated by the code under test.
15+
"""
16+
defaults = {
1017
"api_key": "test_api_key",
1118
"properties": {
1219
"distinct_id": 12345,
@@ -23,11 +30,18 @@ def _mock_event_defaults() -> dict:
2330
"cpu_info": {},
2431
},
2532
}
33+
mocker.patch("reflex.utils.telemetry.get_event_defaults", return_value=defaults)
34+
return defaults
2635

2736

28-
def _patch_event_defaults(mocker: MockerFixture, value):
29-
"""Replace the cached get_event_defaults() so it returns ``value``, bypassing the once_unless_none cache."""
30-
mocker.patch("reflex.utils.telemetry.get_event_defaults", return_value=value)
37+
@pytest.fixture
38+
def httpx_post(mocker: MockerFixture):
39+
"""Mock ``httpx.post`` used by ``telemetry._send``.
40+
41+
Returns:
42+
The mock for ``httpx.post`` so tests can assert on the posted payload.
43+
"""
44+
return mocker.patch("httpx.post")
3145

3246

3347
def test_telemetry():
@@ -84,24 +98,17 @@ def test_disable():
8498
),
8599
],
86100
)
87-
def test_send(mocker: MockerFixture, event, kwargs, expected_props):
88-
httpx_post_mock = mocker.patch("httpx.post")
89-
_patch_event_defaults(mocker, _mock_event_defaults())
90-
101+
def test_send(event_defaults, httpx_post, event, kwargs, expected_props):
91102
telemetry._send(event, telemetry_enabled=True, **kwargs)
92-
httpx_post_mock.assert_called_once()
93-
posted = httpx_post_mock.call_args.kwargs["json"]
103+
httpx_post.assert_called_once()
104+
posted = httpx_post.call_args.kwargs["json"]
94105
assert posted["event"] == event
95106
for key, value in expected_props.items():
96107
assert posted["properties"][key] == value
97108

98109

99-
def test_send_does_not_leak_kwargs_between_events(mocker: MockerFixture):
110+
def test_send_does_not_leak_kwargs_between_events(event_defaults, httpx_post):
100111
"""Per-event kwargs must not leak into a subsequent event's payload."""
101-
httpx_post_mock = mocker.patch("httpx.post")
102-
defaults = _mock_event_defaults()
103-
_patch_event_defaults(mocker, defaults)
104-
105112
telemetry._send("export", telemetry_enabled=True, status="success", duration=1.0)
106113
telemetry._send(
107114
"export",
@@ -111,9 +118,9 @@ def test_send_does_not_leak_kwargs_between_events(mocker: MockerFixture):
111118
duration=2.0,
112119
)
113120

114-
assert httpx_post_mock.call_count == 2
115-
first_props = httpx_post_mock.call_args_list[0].kwargs["json"]["properties"]
116-
second_props = httpx_post_mock.call_args_list[1].kwargs["json"]["properties"]
121+
assert httpx_post.call_count == 2
122+
first_props = httpx_post.call_args_list[0].kwargs["json"]["properties"]
123+
second_props = httpx_post.call_args_list[1].kwargs["json"]["properties"]
117124

118125
assert first_props["status"] == "success"
119126
assert first_props["duration"] == pytest.approx(1.0)
@@ -124,28 +131,22 @@ def test_send_does_not_leak_kwargs_between_events(mocker: MockerFixture):
124131
assert second_props["duration"] == pytest.approx(2.0)
125132

126133
# The cached defaults must not have been polluted by either call.
127-
assert "status" not in defaults["properties"]
128-
assert "duration" not in defaults["properties"]
129-
assert "detail" not in defaults["properties"]
134+
assert "status" not in event_defaults["properties"]
135+
assert "duration" not in event_defaults["properties"]
136+
assert "detail" not in event_defaults["properties"]
130137

131138

132-
def test_send_drops_unknown_kwargs(mocker: MockerFixture):
139+
def test_send_drops_unknown_kwargs(event_defaults, httpx_post):
133140
"""Unknown kwargs must not land in the posted payload."""
134-
httpx_post_mock = mocker.patch("httpx.post")
135-
_patch_event_defaults(mocker, _mock_event_defaults())
136-
137141
telemetry._send("export", telemetry_enabled=True, foo="bar", secret="leak")
138-
httpx_post_mock.assert_called_once()
139-
props = httpx_post_mock.call_args.kwargs["json"]["properties"]
142+
httpx_post.assert_called_once()
143+
props = httpx_post.call_args.kwargs["json"]["properties"]
140144
assert "foo" not in props
141145
assert "secret" not in props
142146

143147

144-
def test_send_drops_none_kwargs(mocker: MockerFixture):
148+
def test_send_drops_none_kwargs(event_defaults, httpx_post):
145149
"""None-valued kwargs for allowed keys are omitted from the posted payload."""
146-
httpx_post_mock = mocker.patch("httpx.post")
147-
_patch_event_defaults(mocker, _mock_event_defaults())
148-
149150
telemetry._send(
150151
"export",
151152
telemetry_enabled=True,
@@ -156,19 +157,17 @@ def test_send_drops_none_kwargs(mocker: MockerFixture):
156157
build_duration=0.05,
157158
zip_duration=None,
158159
)
159-
httpx_post_mock.assert_called_once()
160-
props = httpx_post_mock.call_args.kwargs["json"]["properties"]
160+
httpx_post.assert_called_once()
161+
props = httpx_post.call_args.kwargs["json"]["properties"]
161162
assert props["status"] == "success"
162163
assert props["build_duration"] == pytest.approx(0.05)
163164
assert "detail" not in props
164165
assert "compile_duration" not in props
165166
assert "zip_duration" not in props
166167

167168

168-
def test_prepare_event_merges_properties(mocker: MockerFixture):
169+
def test_prepare_event_merges_properties(event_defaults):
169170
"""``properties`` payloads are merged into the event properties."""
170-
_patch_event_defaults(mocker, _mock_event_defaults())
171-
172171
event = telemetry._prepare_event(
173172
"compile",
174173
properties={"pages_count": 7, "trigger": "initial"},
@@ -183,29 +182,24 @@ def test_prepare_event_merges_properties(mocker: MockerFixture):
183182
assert props["user_os"] == "Test OS"
184183

185184

186-
def test_prepare_event_does_not_mutate_cached_defaults(mocker: MockerFixture):
185+
def test_prepare_event_does_not_mutate_cached_defaults(event_defaults):
187186
"""``_prepare_event`` must not mutate the @once_unless_none cached defaults."""
188-
cached = _mock_event_defaults()
189-
_patch_event_defaults(mocker, cached)
190-
191-
cached_props_snapshot = dict(cached["properties"])
187+
cached_props_snapshot = dict(event_defaults["properties"])
192188

193189
telemetry._prepare_event("init", template="my-template")
194190
telemetry._prepare_event(
195191
"compile",
196192
properties={"pages_count": 3, "duration_ms": 42},
197193
)
198194

199-
assert cached["properties"] == cached_props_snapshot
200-
assert "template" not in cached["properties"]
201-
assert "pages_count" not in cached["properties"]
202-
assert "duration_ms" not in cached["properties"]
195+
assert event_defaults["properties"] == cached_props_snapshot
196+
assert "template" not in event_defaults["properties"]
197+
assert "pages_count" not in event_defaults["properties"]
198+
assert "duration_ms" not in event_defaults["properties"]
203199

204200

205-
def test_prepare_event_properties_override_kwargs(mocker: MockerFixture):
201+
def test_prepare_event_properties_override_kwargs(event_defaults):
206202
"""If both kwargs and properties supply the same key, properties wins."""
207-
_patch_event_defaults(mocker, _mock_event_defaults())
208-
209203
event = telemetry._prepare_event(
210204
"init",
211205
template="from-kwarg",

0 commit comments

Comments
 (0)